了解JavaScript事件流

8/19/2021 事件流

# 了解JavaScript事件流

事件流定义了页面接受事件的顺序。有意思的是,IE和Netscape两家定义了几乎完全相反的事件流方案(事件冒泡事件捕获)。

  1. # 事件冒泡

所谓事件冒泡,是指事件会从DOM树的最深节点开始触发,然后向上传播,就像气泡从水下逐渐冒出水面的过程。

现在所有的浏览器都支持事件冒泡,会一直冒泡到window对象。

<!DOCTYPE html>
<head>
</head>
<body>
    <div>click me</div>
</body>
</html>
1
2
3
4
5
6
7

点击页面中的“click me”后,click 事件会按照如下顺序发生:

  • div
  • body
  • html
  • document
  1. # 事件捕获

所谓事件捕获,是指事件会从最外层的节点开始触发,逐渐到达最深的节点。

现在所有的浏览器也都支持事件捕获,但通常建议使用事件冒泡,特殊情况下可以使用事件捕获。

在事件捕获中查看上节的页面中点击“click me”事件时,click 事件会按照相反顺序发生:

  • document
  • html
  • body
  • div
  1. # DOM事件流

在DOM2 Events规范中规定,事件流把前两节的事件做了整合,DOM事件分为3个阶段:事件捕获到达目标事件冒泡

关系图
选自《Javascript高级程序设计》中画的关系图,基本比较清晰了。
除了IE8及更早版本,现代所有浏览器都已经支持了DOM事件流

  1. # DOM事件委托

所谓事件委托,其实是利用了事件冒泡的机制。假设一个列表里有上百个li元素列表。如果要为每个元素都添加点击事件,那么可想而知,会极大地影响页面的性能。而利用事件冒泡机制,将事件绑定在父元素节点,然后依据target的值来确定是哪个子元素触发。

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
</ul>
1
2
3
4
5
6
ul.addEventListener('click', function(event){
        console.log(event.target);
    },false); // 第三个参数选择事件类型,默认是false:事件冒泡;如果是true,则为事件捕获
1
2
3