• evevt


    Event
    Event 是一个事件对象,当一个事件发生后,和当前事件发生相关的详细信息会被临时存储到一个指定的地方,也就是event对象,以方便我们在需要的时候调用。

    在这一点上,非常类似于飞机当中的黑匣子,会记录着飞机的详细信息,当飞机失事的时候可以在黑匣子中找到相关的信息。
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    <button id="btn">点击</button>
    </body>
    <script>
    var btn = document.getElementById('btn');
    btn.onclick = function () {
    console.log(event); // 查看event对象 MouseEvent {isTrusted: true, screenX: 27, screenY: 160, clientX: 27, clientY: 25, …}
    }
    </script>
    </html>
    在上面的代码中,我们在单击事件的处理函数内打印了event对象,返回值的结果为MouseEvent事件对象。

    当我们在不同的事件中打印event对象,返回的结果会根据不同的事件类型返回不同的结果。
    但是我们在使用的过程中需要考虑一下事件的兼容性,为了更好的兼容性,我们可以采用下面的写法:

    var env = env || window.event
    // 或者
    var env = env || event
    我们还是以上面的例子为例,我们为了兼容性的处理,可以将代码更改为如下的内容:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    <button id="btn">点击</button>
    </body>
    <script>
    var btn = document.getElementById('btn');
    btn.onclick = function (env) {
    //console.log(event); // 查看event对象 MouseEvent {isTrusted: true, screenX: 27, screenY: 160, clientX: 27, clientY: 25, …}
    var env = env || window.event;
    console.log(env)
    }
    </script>
    </html>
    需要注意的是,一般情况下,如果一个函数是事件处理函数,那么推荐将函数的第一个参数设置为事件对象。
    我们通过event对象通常情况下可以处理非常多的事件相关的内容。例如,键盘事件,例如鼠标事件等等相关的操作。

    自定义右键菜单

    下面是自定义右键菜单的案例:
    例如:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
    body {
    font-size: 16px;
    font-family: "KaiTi";
    }
    ul {
    list-style: none;
    margin:0;
    padding: 0;
    }
    a {
    text-decoration: none;
    color: #333;
    }
    .contextmenu {
    200px;
    border: 1px solid #999;
    box-shadow: 3px 3px 3px #ccc;
    background-color: #fff;
    position: absolute;
    top: 10px;
    left: 10px;
    display: none;
    }
    .contextmenu li {
    height: 38px;
    line-height: 38px;
    }
    .contextmenu li a {
    display: block;
    padding:0 20px;
    }
    .contextmenu li a:hover {
    background-color: #ccc;
    color: white;
    font-weight: bold;
    }
    </style>
    </head>
    <body>
    <div class="contextmenu" id="context">
    <ul>
    <li><a href="javascript:;">复制</a></li>
    <li><a href="javascript:;">粘贴</a></li>
    <li><a href="javascript:;">剪切</a></li>
    <li><a href="javascript:;">获取种子</a></li>
    <li><a href="javascript:;">迅雷下载</a></li>
    </ul>
    </div>
    </body>
    <script>
    // 先来获取菜单列表,然后让其在鼠标右击的时候显示出来
    document.oncontextmenu = function (ob) { // ob 表示event事件

    // 兼容event事件
    var e = ob || window.event;

    // 首先获取菜单
    var context = document.getElementById('context');
    // 让菜单显示出来
    context.style.display = "block";


    // 让菜单跟随鼠标位置而移动
    // 需要使用鼠标的坐标,让鼠标的坐标位置为菜单的左上角0,0
    var x = e.clientX;
    var y = e.clientY;


    // 获取窗口的宽度和高度(在浏览器中的可用窗口宽度和高度,当调整窗口大小的时候,获取的值也会变)
    var w = window.innerWidth;
    var h = window.innerHeight;
    console.log("窗口宽度为:"+w,"窗口的高度为:"+h);


    // 将获得的值赋值给菜单的右键菜单,从而实现让右键菜单会出现在鼠标的位置上
    // context.style.left = x + 'px';
    // context.style.top = y + 'px';
    // 重新调整宽度和高度
    context.style.left =Math.min(w - 202,x) + 'px';
    context.style.top = Math.min(h - 230,y) + 'px';


    // 通过return false关闭系统默认菜单
    return false;
    }
    // 当鼠标单击之后,希望关闭右键菜单
    document.onclick = function () {
    var contextmenu = document.getElementById('context');
    // 让菜单在单击之后消失
    contextmenu.style.display = 'none';
    }
    </script>
    </html>
    获取鼠标按键

    在鼠标事件当中,存在有mousedown事件,当我们点击鼠标的时候,可以触发这个事件,但是我们该如何判断具体的鼠标按键呢?

    我们可以先来打印一下鼠标事件函数里面的event对象。

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>

    </body>
    <script>
    document.onmousedown = function (env) {
    var env = env || window.event;
    console.log(env);

    }
    </script>
    </html>
    结果如下:

    MouseEvent {isTrusted: true, screenX: 373, screenY: 213, clientX: 373, clientY: 78, …}
    altKey: false
    bubbles: true
    button: 0
    buttons: 1
    cancelBubble: false
    cancelable: true
    clientX: 373
    clientY: 78
    composed: true
    ctrlKey: false
    currentTarget: null
    defaultPrevented: false
    detail: 1
    eventPhase: 0
    fromElement: null
    isTrusted: true
    layerX: 373
    layerY: 78
    metaKey: false
    movementX: 0
    movementY: 0
    offsetX: 373
    offsetY: 79
    pageX: 373
    pageY: 78
    path: (3) [html, document, Window]
    relatedTarget: null
    returnValue: true
    screenX: 373
    screenY: 213
    shiftKey: false
    sourceCapabilities: InputDeviceCapabilities {firesTouchEvents: false}
    srcElement: html
    target: html
    timeStamp: 4162.865000020247
    toElement: html
    type: "mousedown"
    view: Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
    which: 1
    x: 373
    y: 78
    __proto__: MouseEvent
    上面这一系列的值,就是打印出来的结果,我们可以通过button属性来具体的获取我们操作的到底是哪个鼠标按键。

    console.log(env.button);
    根据点击的结果,我们可以分清,左键显示0,中间键显示1,而右键显示2。

    在很多操作的时候,我们就可以根据返回给我们的数字来进行鼠标按键判断。
    获取鼠标坐标

    通过evnet对象当中的内容,我们可以非常轻易的获取鼠标的坐标。

    例如:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>

    </body>
    <script>
    document.onmousemove = function (env) {
    var env = env || window.event;
    console.log(env.clientX,env.clientY); // clientX 鼠标x轴坐标,clientY鼠标y轴坐标
    }
    </script>
    </html>
    当鼠标在一个元素中移动时,我们如果想要获取鼠标在一个元素中的坐标,我们可以采用下面的写法:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
    .d1 {
    300px;
    height: 300px;
    background-color: #cccccc;
    }
    </style>
    </head>
    <body>
    <div class="d1"></div>
    </body>
    <script>
    var d1 = document.getElementsByClassName('d1')[0];
    d1.onmousemove = function (env) {
    var env = env || window.event;

    // 鼠标坐标
    var mouseX = env.clientX;
    var mouseY = env.clientY;

    // 元素坐标
    var left = this.offsetLeft;
    var top = this.offsetTop;

    // 获取鼠标在元素当中的坐标
    var d1_mouse_x = mouseX - left ;
    var d1_mouse_y = mouseY - top;

    console.log('鼠标在元素内的横坐标是:' + d1_mouse_x + ',纵坐标是:' + d1_mouse_y);
    }
    </script>
    </html>
    下面我们来根据鼠标事件和event对象来完成一个案例:图层拖拽。

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>图层拖拽</title>
    <style type="text/css">
    .box {
    200px;
    height: 200px;
    background-color: orange;
    border: 2px solid pink;
    cursor: pointer;
    position: absolute;
    left:100px;
    top: 20px;
    }
    </style>
    </head>
    <body>
    <h1>图层拖拽</h1>
    <hr>
    <div class="box" id="box"></div>
    </body>
    <script type="text/javascript">

    // 获取元素绑定事件
    var oBox = document.getElementById("box");
    oBox.onmousedown = function (env) {
    var env = env || window.event;

    // 获取一下鼠标在div上的位置
    var left = env.clientX - oBox.offsetLeft;
    var top = env.clientY - oBox.offsetTop;

    // 为了方便查看效果,当鼠标点击之后,改变一下颜色
    oBox.style.background = "#999";

    oBox.onmousemove = function (env) {
    var env = env || window.event;

    var x = env.clientX;
    var y = env.clientY;
    oBox.style.left = (x - left) + 'px';
    oBox.style.top = (y - top) + 'px';
    }


    }

    oBox.onmouseup = function () {
    oBox.style.background = "orange";
    oBox.onmousemove = function (){}
    }

    </script>
    </html>
    获取键盘按键

    我们常用的键盘事件有keydown、keyup、keypress三个。

    我们绑定了键盘事件之后,event对象就会转换为相应的键盘事件。

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>

    </body>
    <script>
    document.onkeydown = function (env) {
    var env = env || window.event;
    console.log(env); // KeyboardEvent
    }
    </script>
    </html>
    那么我们该如何判断键盘按键呢?
    在键盘事件中的event事件中有一个属性keyCode可以返回键盘所对键位的ascii码。

    <script type="text/javascript">
    // document.onkeydown = function (env) { // 这个事件的缺点是一些符号显示不出
    // // 通过event对象keycode属性来实现获取按键
    // var env = env || window.event;
    // console.log(env.keyCode); // 可以得到按键对应的ascii码
    // // 可以通过fromCharCode来将ascii码转换成对应的字符串
    // console.log(String.fromCharCode(env.keyCode));
    // console.log("按键按下");
    // }

    document.onkeypress = function (env) {//这个事件可以将字符+符号都显示出来,但是控制键不行
    // 通过event对象keycode属性来实现获取按键
    var env = env || window.event;
    console.log(env.keyCode); // 可以得到按键对应的ascii码
    // 可以通过fromCharCode来将ascii码转换成对应的字符串
    console.log(String.fromCharCode(env.keyCode));
    console.log("按键按下");
    }


    document.onkeyup = function () {
    console.log("按键抬起");
    }


    </script>
    我们还可以通过env.key来获取按键信息,下面是一个小demo,通过键盘的上下左右来移动元素。

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
    .d1 {
    100px;
    height: 100px;
    background-color: red;
    position: absolute;
    left: 0;
    top: 0;
    }
    </style>
    </head>
    <body>
    <div class="d1"></div>
    </body>
    <script>
    var d1 = document.getElementsByClassName('d1')[0];
    console.log(d1)
    document.onkeydown = function (env) {
    var env = env || window.event;
    // console.log(env.key)
    var keybor = env.key;
    console.log(keybor)
    switch (keybor) {
    case 'ArrowUp':
    d1.style.top = d1.offsetTop - 5 + 'px';
    break;
    case 'ArrowDown':
    d1.style.top = d1.offsetTop + 5 + 'px';
    break;
    case 'ArrowLeft':
    d1.style.left = d1.offsetLeft - 5 + 'px';
    break;
    case 'ArrowRight':
    d1.style.left = d1.offsetLeft + 5 + 'px';
    break;
    }
    }
    </script>
    </html>
    我们也可以来判断alt键和ctrl键是否被按下。

    document.onmousedown = function (event) {
    var env = env || window.event;
    console.log(env.altKey); // 当我们进行alt键操作的时候,会返回true,否则返回false
    }
    <!doctype html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport"
    content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    </head>
    <body>

    </body>
    <script>
    document.onmousedown = function (event) {
    var env = env || window.event;
    console.log(env.ctrlKey); // 当我们进行ctrl键操作的时候,会返回true,否则返回false
    }
    </script>
    </html>
    上面我们在判断按键时,使用了keyCode,我们还可以通过which来进行判断。

    document.onkeydown = function (event) {
    var env = event || window.event;
    // console.log(env.ctrlKey); // 当我们进行ctrl键操作的时候,会返回true,否则返回false
    console.log(String.fromCharCode(env.which))
    }
    兼容性问题:

    IE:

    支持keyCode

    不支持which和charCode,二者值为 undefined

    在Firefox下:

    支持keyCode,除功能键外,其他键值始终为 0

    支持which和charCode,二者的值相同

    在Opera下:

    支持keyCode和which,二者的值相同

    不支持charCode,值为 undefined

    页面中位置的获取

    上面我们使用过clientX和clientY,通过这两个属性,我们可以获取鼠标的坐标。

    在实际的应用中,我们还经常碰到另外一些属性,

    如:

    event.offsetX
    event.clientX
    event.pageX
    event.scrrenX
    图例:

    event.layerX
    event.layerY


    eventX
    eventY


    浏览器的默认行为

    很多时候,我们的浏览器都具备一些默认的行为,这些默认的行为在某些时刻我们需要取消或者屏蔽掉,例如当我们在我们自己的网页中自定义了右键菜单,那么我们就希望屏蔽掉浏览器的右键菜单,所以我们可以如下:

    document.oncontextmenu = function () {
    return false;
    }
    当然,我们也可以采用更加标准的写法:

    if(e.preventDefault){
    e.preventDefault();
    }else{
    window.event.returnValue = false; // 兼容ie
    }
    我们也可将上面的写法进行封装处理:

    //阻止浏览器的默认行为
    function stopDefault( e ) {
    //阻止默认浏览器动作(W3C)
    if ( e && e.preventDefault )
    e.preventDefault();
    //IE中阻止函数器默认动作的方式
    else
    window.event.returnValue = false;
    return false;
    }
    冒泡

    什么是冒泡

    我们可以先来看下面的案例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
    div {
    padding:40px;
    }
    #div1 {
    background-color: red;
    }
    #div2 {
    background-color: pink;
    }
    #div3 {
    background-color: orange;
    }
    </style>
    </head>
    <body>
    <div id="div1">
    <div id="div2">
    <div id="div3"></div>
    </div>
    </div>
    </body>
    <script>
    var d1 = document.getElementById('div1');
    var d2 = document.getElementById('div2');
    var d3 = document.getElementById('div3');

    function fn1() {
    alert(this.id);
    }

    // 绑定事件
    d1.onclick = fn1;
    d2.onclick = fn1;
    d3.onclick = fn1;
    </script>
    </html>
    在上面的代码中,会发现,我们点击时会弹出多个弹窗,为什么会出现这种情况呢?

    原因是因为标签的物理结构影响了事件,产生了我们看到的结果。

    而出现的这种情况,就是我们说的事件冒泡。
    事件冒泡:当一个元素接受到事件的时候,会把它接受到的所有传播给它的父级,一直到顶层window。也就是事件冒泡机制。
    我们可以看另一个演示的实例:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    <button id="btn">点击</button>
    </body>
    <script>
    var btn = document.getElementById('btn');
    btn.onclick = function () {
    alert(123);
    };
    document.onclick = function () {
    alert(456);
    }
    </script>
    </html>
    你会发现在上面的代码中,我们点击一下按钮,就会弹出123,紧接着弹出456.

    出现这种情况的原因是因为我们点击按钮时,动作从按钮传递到了document,所以二者才会同时触发。

    再回到上面的案例当中,上面案例的结构如下:

    <div id="div1">
    <div id="div2">
    <div id="div3"></div>
    </div>
    </div>
    即使我们将中间的div2注释掉,你会发现,当我们点击div3时,同样出现了div1被触发。原因如下:
    给元素加一个事件,其实严谨的说应该是给元素添加事件处理函数。
    我们给div1绑定事件,oDiv1.onclick = fn1;告诉div1,如果接受到了一个点击事件,那么就去执行fn1。我们称之这种行为为事件函数绑定。

    而我们将oDiv1.onclick = fn1注释掉后,只是将绑定的事件处理函数给取消掉了,但是并没有让它的事件消失。
    换个角度说我们点击任何一个元素,这个元素是否能获取这个点击事件呢?
    答案是必须的。但是你说为什么点击的时候没什么发生呢?是因为你没有绑定发生点击之后该要办的事。

    事件冒泡是默认存在的,我们在日常的工作的时候,很容易被这个情况所影响到。

    例如下面的案例,我们的本意是,点击按钮出现一个内容框:

    <!doctype html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport"
    content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
    .d1 {
    300px;
    height: 300px;
    border:2px solid red;
    display: none;
    }
    </style>
    </head>
    <body>
    <button id="btn">click me</button>
    <div class="d1"></div>
    </body>
    <script>
    var btn = document.getElementById('btn');
    var d1 = document.getElementsByClassName('d1')[0];

    btn.onclick = function () {
    d1.style.display = 'block';
    };
    // 我们同时希望点击网页的其他地方将d1隐藏
    document.onclick = function () {
    d1.style.display = 'none';
    };
    </script>
    </html>
    我们发现似乎很符合 逻辑的情况却不能实现点击显示小框。而这就是我们的事件冒泡所产生。

    不妨尝试将 d1.style.display = 'none'; 这句代码加上定时,你就能够发现元素是出现然后自动消失的。
    而原因就是单击的动作从btn传递到了document。

    那么我们该如何阻止这种行为呢?

    可以采用下面这个函数进行阻止冒泡:

    function stopBubble(e) {
    //如果提供了事件对象,则这是一个非IE浏览器
    if ( e && e.stopPropagation )
    //因此它支持W3C的stopPropagation()方法
    e.stopPropagation();
    else
    //否则,我们需要使用IE的方式来取消事件冒泡
    window.event.cancelBubble = true;
    }
    例如上面的例子:

    <!doctype html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport"
    content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
    .d1 {
    300px;
    height: 300px;
    border:2px solid red;
    display: none;
    }
    </style>
    </head>
    <body>
    <button id="btn">click me</button>
    <div class="d1"></div>
    </body>
    <script>
    var btn = document.getElementById('btn');
    var d1 = document.getElementsByClassName('d1')[0];

    btn.onclick = function (e) {
    d1.style.display = 'block';
    stopBubble(e); // 阻止冒泡
    };
    // 我们同时希望点击网页的其他地方将d1隐藏
    document.onclick = function () {
    d1.style.display = 'none';
    };

    function stopBubble(e) {
    //如果提供了事件对象,则这是一个非IE浏览器
    if ( e && e.stopPropagation )
    //因此它支持W3C的stopPropagation()方法
    e.stopPropagation();
    else
    //否则,我们需要使用IE的方式来取消事件冒泡
    window.event.cancelBubble = true;
    }
    </script>
    </html>
    那么冒泡是否都是坏事呢?也不尽然,我们也可以利用冒泡来实现一些功能,例如下面的分享到的功能:

    <!doctype html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport"
    content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
    #div1 {
    100px;
    height: 200px;
    background: red;
    position: absolute;
    left: -100px;
    top: 100px;
    }
    #div2 {
    30px;
    height: 70px;
    position: absolute;
    right: -30px;
    top: 70px;
    background: #000;
    color: #ffffff;
    text-align: center;
    }
    </style>
    </head>
    <body>
    <div id="div1">
    <div id="div2">分享到</div>
    </div>
    </body>
    <script>
    var d1 = document.getElementById('div1');
    d1.onmouseover = function () {
    this.style.left = 0;
    };
    d1.onmouseout = function () {
    this.style.left = '-100px';
    };
    </script>
    </html>
    上面的代码中,我们通过给div1设定了事件,但是这个事件却是被div2传递过来的动作所触发,这种模式我们称之为事件委托.

    小练习

    隔行换色:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    <ul id="list">
    <li>aaaaa</li>
    <li>aaaaa</li>
    <li>aaaaa</li>
    <li>aaaaa</li>
    <li>aaaaa</li>
    </ul>
    </body>
    <script>
    var list = document.getElementById('list').getElementsByTagName('li');
    for(var i=0;i<list.length;i++){
    list[i].style.backgroundColor = i % 2==0 ? "red" : "green";
    }
    </script>
    </html>

  • 相关阅读:
    第3节:vue-router如何参数传递
    第2节:vue-router配置子路由
    Vue-router笔记 第1节:Vue-router入门
    vue-cli模版解读
    Vue-cli项目结构讲解
    vue-cli笔记
    实例属性
    实例方法-扩展器-生命zhou
    父子组件
    伪数组转为数组 Array.prototype.slice.call(arguments)
  • 原文地址:https://www.cnblogs.com/wufenfen/p/11444610.html
Copyright © 2020-2023  润新知