手记

理解JavaScript事件

大纲

  • 事件级别
  • 事件模型
  • 事件流
  • 事件对象
  • 自定义事件

一、事件级别

1.1.DOM0

element.on click = function(){}

1.2.DOM2

element.addEventListener('click', function(){}, false)

1.3.DOM3

// 在dom2上面增加了很多新的事件,比如鼠标,键盘事件
element.addEventListener('keyup', function(){}, false);

二、事件模型

事件模型分为2种:事件冒泡、事件捕获。

2.1.事件冒泡:

简单来说,事件冒泡就是你向水里扔一块小小的石头,它在水的中央溅起一圈圈涟漪, 那波浪没抵达岸边就已消逝;这个过程就像事件冒泡,从事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点。

2.2.事件捕获:

打个比如就是看美国大片经常有这片段:卫星追踪某个地方点,从全球点范围一点点地缩小到最精确的某个地方点,这个过程相似事件捕获的用意在于在事件到达预定目标之前捕获它。

三、事件流

事件流描述的是从页面中接收事件的顺序。

事件流分三个阶段:事件捕获阶段 => 事件目标阶段 => 事件冒泡阶段

大白话来说:当点击一个元素时,首先事件进行捕获阶段,从window对象进入,然后进入到事件目标(当前元素),最后通过冒泡顶到上层window对象。

事件冒泡和事件捕获事件流实例:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Event</title>
    <style>
        #box {
            width: 100px;
            height: 100px;
            color: #fff;
            text-align: center;
            line-height: 100px;
            background: #f00;
        }
    </style>
</head>
<body>
<div id="box">BOX</div>

<script>
    // window
    // 第三个参数默认为false,
    // true代表在事件捕获时触发,
    // false代表在事件的冒泡时触发。
    window.addEventListener('click', function (event) {
        console.log('捕获阶段=> window');
    }, true)

    // document
    document.addEventListener('click', function (event) {
        console.log('捕获阶段=> document');
    }, true)

    // html
    document.documentElement.addEventListener('click', function (event) {
        console.log('捕获阶段=> html');
    }, true)

    // body
    document.body.addEventListener('click', function (event) {
        console.log('捕获阶段=> body');
    }, true)

    // box
    box.addEventListener('click', function (event) {
        console.log('捕获阶段=> box');
    }, true)

    // window
    window.addEventListener('click', function (event) {
        console.log('冒泡阶段=> window');
    }, false)

    // document
    document.addEventListener('click', function (event) {
        console.log('冒泡阶段=> document');
    }, false)

    // html
    document.documentElement.addEventListener('click', function (event) {
        console.log('冒泡阶段=> html');
    }, false)

    // body
    document.body.addEventListener('click', function (event) {
        console.log('冒泡阶段=> body');
    }, false)

    // box
    box.addEventListener('click', function (event) {
        console.log('冒泡阶段=> box');
    }, false)
</script>
</body>
</html>

测试:

从上面的代码我们知道了事件捕获和事件冒泡的具体流程:

事件捕获具体流程: window => document => html => body => 目标

事件冒泡具体流程: 目标 => body => html => document => window

四、事件对象

在触发DOM上的某个事件时,会产生一个事件对象event,这个对象中包含着所有与事件有关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。

例如,鼠标操作导致的事件对象中,会包含鼠标位置的信息,而键盘操作导致的事件对象中,会包含与按下的键有关的信息。所有浏览器都支持event对象,但支持方式不同。

let box = document.getElementById('box')
box.addEventListener('click', function (event) {
    console.log(event);
}, false)

4.1.event对象常用的属性和方法:

属性/方法 说  明
bubbles 表明事件是否冒泡
cancelable 表明是否可以取消事件的默认行为
currentTarget 其事件处理程序当前正在处理事件的那个元素
defaultPrevented 为true表示已经调用了preventDefault()(DOM3级事件中新增)
detail 与事件相关的细节信息
eventPhase 调用事件处理程序的阶段:1表示捕获阶段,2表示“处于目标”,3表示冒泡阶段
preventDefault() 取消事件的默认行为。如果cancelable是true,则可以使用这个方法
stopPropagation() 取消事件的进一步捕获或冒泡。如果bubbles为true,则可以使用这个方法
target 事件的目标
trusted 为true表示事件是浏览器生成的。为false表示事件是由开发人员通过JavaScript创建的(DOM3级事件中新增)
type 被触发的事件的类型
stopImmediatePropagation() 只读 取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用(DOM3级事件中新增)

4.2.IE中的事件对象

与访问DOM中的event对象不同,在使用DOM0级方法添加事件处理程序时,event对象作为window对象的一个属性存在:

var box = document.getElementById("box");
box. = function(){
    var event = window.event;
    console.log(event.type);     //"click"
};

五、自定义事件

方法一:Event,不能定义参数

var myEvent = new Event('eventName');

window.addEventListener('eventName', function () {
    console.log('eventName');
})
window.dispatchEvent(myEvent);

方法二:CustomEvent,可以定义参数

var myEvent = new CustomEvent('eventName', {
    detail: {
        name: 'bob',
        like: 'coding'
    }
});
window.addEventListener('eventName', function (e) {
    console.log(e.detail);
    // {name: "bob", like: "coding"}
})

// 随后在对应的元素上触发该事件,兼容IE
if (window.dispatchEvent) {
    window.dispatchEvent(myEvent);
} else {
    // IE8低版本兼容,使用fireEvent
    window.fireEvent(myEvent);
}

自定义事件常用场景:

  1. 抓取页面的时候
  2. 你在某个按钮绑定了事件想触摸你用户点击那个按钮,就可以用自定义事件去触发
  3. 定时器触发自定义事件

总结

通过本章学习了js的事件级别,事件模型,事件流和事件对象,理解这些概念非常重要,关于JS事件类型非常多,所以下章再写,希望对你学习有帮助,thanks!

8人推荐
随时随地看视频
慕课网APP