了解JavaScript事件流
will.wei 8/19/2021 事件流
# 了解JavaScript事件流
事件流定义了页面接受事件的顺序。有意思的是,IE和Netscape两家定义了几乎完全相反的事件流方案(事件冒泡和事件捕获)。
# 事件冒泡
所谓事件冒泡,是指事件会从DOM树的最深节点开始触发,然后向上传播,就像气泡从水下逐渐冒出水面的过程。
现在所有的浏览器都支持事件冒泡,会一直冒泡到window对象。
<!DOCTYPE html>
<head>
</head>
<body>
<div>click me</div>
</body>
</html>
1
2
3
4
5
6
7
2
3
4
5
6
7
点击页面中的“click me”后,click 事件会按照如下顺序发生:
- div
- body
- html
- document
# 事件捕获
所谓事件捕获,是指事件会从最外层的节点开始触发,逐渐到达最深的节点。
现在所有的浏览器也都支持事件捕获,但通常建议使用事件冒泡,特殊情况下可以使用事件捕获。
在事件捕获中查看上节的页面中点击“click me”事件时,click 事件会按照相反顺序发生:
- document
- html
- body
- div
# DOM事件流
在DOM2 Events规范中规定,事件流把前两节的事件做了整合,DOM事件分为3个阶段:事件捕获、到达目标、事件冒泡。
选自《Javascript高级程序设计》中画的关系图,基本比较清晰了。
除了IE8及更早版本,现代所有浏览器都已经支持了DOM事件流。
# DOM事件委托
所谓事件委托,其实是利用了事件冒泡的机制。假设一个列表里有上百个li
元素列表。如果要为每个元素都添加点击事件,那么可想而知,会极大地影响页面的性能。而利用事件冒泡机制,将事件绑定在父元素节点,然后依据target的值来确定是哪个子元素触发。
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
1
2
3
4
5
6
2
3
4
5
6
ul.addEventListener('click', function(event){
console.log(event.target);
},false); // 第三个参数选择事件类型,默认是false:事件冒泡;如果是true,则为事件捕获
1
2
3
2
3