DOM事件流

131 阅读2分钟

DOM事件流描述的是从页面中接收事件的顺序;事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即 DOM 事件流!

一.DOM事件流

比如我们给一个div注册了一个点击事件:

DOM事件流分为3个阶段:

  1. 捕获阶段
  2. 当前目标阶段
  3. 冒泡阶段

事件冒泡: IE 最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到到 DOM 最顶层节点的过程。

事件捕获: 网景最早提出,由 DOM 最顶层节点开始,然后逐级向下传播到到最具体的元素接收的过程。

需要注意

  1. JS 代码中只能执行捕获或者冒泡其中的一个阶段。
  2. onclick 和 attachEvent 只能得到冒泡阶段。
  3. addEventListener(type, listener[, useCapture])第三个参数如果是 true,表示在事件捕获阶段调用事件处理程序;如果是 false(不写默认就是false),表示在事件冒泡阶段调用事件处理程序。
  4. 实际开发中我们很少使用事件捕获,我们更关注事件冒泡。
  5. 有些事件是没有冒泡的,比如 onblur、onfocus、onmouseenter、onmouseleave
  6. 事件冒泡有时候会带来麻烦,有时候又会帮助很巧妙的做某些事件,所以它有利也有弊。
<body>
    <div class="father">
        <div class="son">son盒子</div>
    </div>
    <script>
        //  冒泡阶段:如果addEventListener第三个参数是 false 或者省略那么则处于冒泡阶段  son -> father ->body -> html -> document
        var son = document.querySelector('.son');
        son.addEventListener('click', function() {
            alert('son');
        }, false);
        var father = document.querySelector('.father');
        father.addEventListener('click', function() {
            alert('father');
        }, false);
        document.addEventListener('click', function() {
            alert('document');
        })
    </script>
</body>

代码执行结果:

二.阻止事件冒泡

  • 标准写法:利用事件对象里面的 stopPropagation()方法

    e.stopPropagation()

  • 非标准写法:IE 6-8 利用事件对象 cancelBubble 属性

    e.cancelBubble = true

三.事件委托

  • 事件委托:称为事件代理, 在 jQuery 里面称为事件委派。
  • 事件委托的原理:不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。
  • 事件委托作用:我们只操作了一次 DOM ,提高了程序的性能。
<body>
    <ul>
        <li>
            <div>事件委托</div>
        </li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        ul.addEventListener('click', function(e) {
            // e.target 这个可以得到我们点击的对象
            e.target.style.backgroundColor = 'purple';
        })
    </script>
</body>