DOM事件流、事件委托
事件就是文档或浏览器窗口中发生的一些特定的交互瞬间,而事件流描述的是从页面中接收事件的顺序。
-
DOM事件级别
- 事件流(冒泡、捕获、DOM事件流)
- 事件对象
- 事件委托
-
可以想象在一张纸上的一组同心圆,如果你把手指放在圆心上,那么你的手指指向的其实不是一个圆,而是纸上所有的圆。放到实际页面中就是,你点击一个按钮,事实上你还同时点击了按钮所有的父元素。
DOM事件级别
DOM级别可分为:DOM0级、DOM1级、DOM2级、DOM3级
DOM事件处理为:DOM0级处理、DOM2级处理、DOM3级处理
事件流
- 事件冒泡
IE事件的事件流叫做事件冒泡。即事件开始时,由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点。
如代码展示:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>my-learning</title>
</head>
<body>
<div id="app">
<button id="clickMe">点击</button>
</div>
<script>
var button = document.getElementById('clickMe');
var oDiv = document.getElementById('app')
button.onclick = function () {
console.log('1-- You click Button');
};
oDiv.onclick = function () {
console.log('2-- You click app');
};
document.body.onclick = function () {
console.log('3-- You click body');
};
document.onclick = function () {
console.log('4-- You click document');
};
window.onclick = function () {
console.log('5-- You click window');
};
</script>
</body>
</html>
控制台输出情况:
点击了button,这个点击事件就会一次传播到:div body document window,逐级向上传播。
- 事件捕获
与事件冒泡相反。当某个事件发生时,父元素应该更早接收到事件,具体元素则最后接收到事件。拿上面的代码来看的化,事件发生顺序就是:window document body button
- DOM事件流
事件流又叫事件传播。
- DOM2级事件中规定事件流包含3个阶段:
- 捕获阶段
- 处于目标阶段
- 冒泡阶段
首先发生的是事件捕获,此时事件还没有传递到目标节点对象上,所以我们就有机会在这个阶段进行事件的截获。再就是目标节点接收到事件,最后是事件冒泡阶段,可以在这个阶段对事件做出处理和响应。
- 事件捕获阶段
- 事件从文档的根节点触发,随着DOM树的结构向事件的目标节点出发。经过各个层次的DOM树节点,并在各节点上触发捕获事件,直到到达事件的目标节点。捕获阶段的主要任务是建立传播路径,在冒泡阶段,事件会通过这个路径回溯到文档根节点,当事件发生时,首先发生的是事件捕获,为父元素截获事件提供了机会。
- 处于目标阶段
- 事件到了具体元素时,在具体元素上发生,并且被看成冒泡阶段的一部分。随后冒泡阶段发生。
- 事件冒泡阶段
- 与捕获阶段相反,从最具体的目标对象开始,一层一层地向上传递,直到window对象。
事件委托
事件委托也叫事件代理,事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
每个函数都是对象,都会占用内存,所以当我们的页面中所包含的事件数量较多时,若给每个节点绑定一个事件,加上事件处理程序,就会造成性能很差。
当某个元素节点是后来通过JS动态添加到页面的,此时若提前对它进行绑定,但此时元素并不存在,所以绑定事件会失败。
此时,解决以上两个问题的方案就是使用事件委托
。
- 优点:
- 减少内存消耗,提高性能
- 不需要给子节点注销事件
- 动态绑定事件
阻止事件冒泡
我们可以使用``event.stopPropagation()方法阻止事件冒泡过程,以防止事件冒泡而带来不必要的错误
var button = document.getElementById('clickMe');
var oDiv = document.getElementById('app')
button.onclick = function () {
console.log('1-- You click Button');
event.stopPropagation();
};
oDiv.onclick = function () {
console.log('2-- You click app');
};
document.body.onclick = function () {
console.log('3-- You click body');
};
document.onclick = function () {
console.log('4-- You click document');
};
window.onclick = function () {
console.log('5-- You click window');
};
控制台输出: