1.事件概述
1.1 什么是事件
事件是可以被 JS 检测到的行为,实质上是一种交互操作。
例如:我们可以给某按钮添加一个 onclick
(点击)事件,当用户点击时触发某个函数。
1.2 事件的作用
- 各个元素之间可以借助事件来进行交互
- 用户和页面之间也可以通过事件来交互
- 后端和页面之间也可以通过事件来交互(减轻服务器压力)
注意:事件通常会与函数进行配合,当事件发生了函数才会执行,事件的本质就是一次交互操作。
1.3 事件传递
JS 中规定:
事件不仅能够和触发者交互,还会在特定情况下沿着 dom tree 逐级传递,和 dom tree 中的各个节点进行交互。而 JS 中的这种机制被称为事件传递机制。
事件交互的两种方式:
- 事件冒泡:
事件从最具体的元素开始,沿着 DOM 树逐级向上依次触发,直至最不具体的元素停止。
因为<div> <button>点我</button> </div> var div = document.querySelector("div"); var button = document.querySelector("button"); button.onclick = function() { alert("按钮被点击了!"); } div.onclick = function() { alert("div 被点击了!"); }
div
包含了button
,所以button
在 DOM 树中是div
的子节点,所以点击按钮会向上冒泡,先是button
触发了事件,紧接着是div
触发了事件。 - 事件捕获:
事件从最不具体的元素开始,沿着 DOM 树逐级向下依次触发,直至最具体的元素停止。
将第三个参数设置为<div> <button>点我</button> </div> var div = document.querySelector("div"); var button = document.querySelector("button"); div.addEventListener("click", function() { alert("div 被点击了"); }, true); button.addEventListener("click", function() { alert("button 被点击了"); }, true);
true
,这样点击button
时就会触发事件捕获,先是div
触发事件,紧接着button
触发事件。
由图可知捕获过程要先于冒泡过程。
W3C 规定:事件冒泡 + 事件捕获 + 事件真正的触发者等各个分支构成了 JS 的事件机制。
注意:如果没有特殊情况,均采用事件冒泡。
2.非 IE 浏览器中的 事件绑定
2.1 HTML 事件
绑定操作发生在 HTML 代码中的事件,称为 HTML 事件。
语法:
on + 事件 = 函数();函数();函数();...
例如:
<div class="d1" onclick="test1();test2()">
<div class="d2" onclick="test2()"></div>
</div>
var div1 = document.querySelector(".div1");
var div2 = document.querySelector(".div2");
function test1() {
console.log("这是第一个函数");
}
function test2() {
console.log("这是第二个函数");
}
在上述 HTML 代码中,分别给 d1 和 d2 绑定了效果不同的 HTML 事件。
注意:
- HTML 事件采用冒泡机制来处理事件。即 点击 d2 时会先执行 d2 的绑定事件(test2()函数),然后采用事件冒泡将事件传递给上一级 DOM 节点(d1),然后 d1 执行自己的绑定事件。
- 函数执行的顺序按照绑定事件时函数的顺序为准。
2.1.1 移除 HTML 事件的方式
语法:
元素.setAttribute("on+事件名", null);
例如:
button.setAttribute("onclick", null);
2.1.2 HTML 事件的缺陷
- 耦合性太强,修改一处另一处也要修改。
- 当函数没有加载成功时,用户去触发事件就会报错。
2.2 DOM 0级事件
在 JS 脚本中,直接通过 on+事件名
方式绑定的事件称为是 DOM0 级事件。
语法:
元素.on+事件名 = function() {需要执行的语句}
例如:
button.onclick = function() {
console.log("按钮被点击了");
}
注意:以冒泡机制来处理事件,不存在兼容问题。
2.2.1 DOM0 级事件移除方式
语法:
元素.on+事件名 = null;
例如:
button.onclick = null;
2.2.2 DOM0 级事件的缺陷
一次只能绑定一个触发函数,如果同时绑定多个触发函数,则以最后一个为准。
2.3 DOM 2级事件
在 JS 脚本中,通过 addEventListener
函数绑定的事件被称为 DOM2级事件。
语法:
元素.addEventListener(type, listener, useCapture);
- type:事件类型(没有
on
) - listener:监听函数,绑定的函数
- useCapture:是否使用捕获机制。如果不写,默认值为
false
。
注意:DOM2 级事件可以绑定多个函数,执行顺序按照函数熟悉的顺序。
例如:
var button = document.querySelector("button");
button.addEventListener("click", function() {
console.log(11);
}, true);
button.addEventListener("click", function() {
console.log(22);
}, true);
上述代码表示给按钮添加了两个 DOM2 级点击事件,事件传递采用事件捕获的方式。
2.3.1 DOM2 级事件移除方式
语法:
node.removeEventListener(type, 外部函数名, useCapture);
例如:
var button = document.querySelector("button");
button.addEventListener("click", clickEvent, false);
button.removeEventListener("click", clickEvent, false);
function clickEvent() {
console.log(22);
}
注意:DOM2 级事件中如果绑定函数为匿名函数则无法解除。能够删除的只能是外部函数,并且移除时的参数要与添加时的参数完全一致。
3.IE 浏览器中的 事件绑定
HTML 事件处理程序 等同于非 IE
DOM0 级事件 等同于非 IE
-
DOM2 级事件
在 JS 脚本中,通过attachEvent
函数绑定事件
语法:元素.attachEvent(type, listener);
- type:事件类型(有
on
) - listener:监听函数,绑定的函数
注意:如果绑定多个函数,按照函数书写的倒序执行。
例如:
var div1 = document.querySelector(".d1"); var div2 = document.querySelector(".d2"); div1.attachEvent("onclick", test1); div2.attachEvent("onclick", test1);
不支持 IE11。
- type:事件类型(有
3.1 移除 DOM2 级事件
语法:
元素.detachEvent(type, listener);