事件监听中的冒泡流和捕获流有趣现象

事件监听中的冒泡流和捕获流有趣现象

这两天在看js权威指南的时候看见addEventListener的第二个参数为使用哪一种事件流,实践了一下,然后想到一个有趣的事,如果两个一起用会怎么样。
首先看看他们的原理
以下摘自百度百科

1、冒泡事件流

当事件在某一DOM元素被触发时,例如用户在客户名字节点上点击鼠标,事件将跟随着该节点继承自的各个父节点冒泡穿过整个的DOM节点层次,直到它遇到依附有该事件类型处理器的节点,此时,该事件是onclick事件。在冒泡过程中的任何时候都可以终止事件的冒泡,在遵从W3C标准的浏览器里可以通过调用事件对象上的stopPropagation()方法,在Internet Explorer里可以通过设置事件对象的cancelBubble属性为true。如果不停止事件的传播,事件将一直通过DOM冒泡直至到达文档根。
如果想创建一个捕捉事件,在支持W3C 事件模型的浏览器中,将addEventListener的第三个参数设为true就好了。例如:

2、捕获事件流

事件的处理将从DOM层次的根开始,而不是从触发事件的目标元素开始,事件被从目标元素的所有祖先元素依次往下传递。在这个过程中,事件会被从文档根到事件目标元素之间各个继承派生的元素所捕获,如果事件监听器在被注册时设置了useCapture属性为true,那么它们可以被分派给这期间的任何元素以对事件做出处理;否则,事件会被接着传递给派生元素路径上的下一元素,直至目标元素。事件到达目标元素后,它会接着通过DOM节点再进行冒泡。

那么当把两者同时用的时候会发生什么呢
下面做一个测试

        one.addEventListener('click', function() {
            console.log('two');
        }, false);
        one.addEventListener('click', function() {
            console.log('one');
        }, true);

上边这段代码在one(div)上绑定了两个事件,属于不同的事件流,输出如下

two
one

再将其代码反过来如下

        one.addEventListener('click', function() {
            console.log('one');
        }, true);
        one.addEventListener('click', function() {
            console.log('two');
        }, false);

则输出也反过来了

one
two

由此可见在单一元素的时候,执行顺序与为什么流无关,与绑定事件的顺序有关

而当出现两个元素,其中one是two父元素的时候,事件代码如下

        one.addEventListener('click', function() {
            console.log('two');
        }, false);
        one.addEventListener('click', function() {
            console.log('one');
        }, true);
        two.addEventListener('click', function() {
            console.log('four');
        }, false);
        two.addEventListener('click', function() {
            console.log('three');
        }, true);

当在two上触发click事件,可以看到如下输出

one
four
three
two

实验证明,先会触发父级捕获流的事件,然后才触发子元素的事件,最后触发父级冒泡流事件,其中对于最上层的子元素也就是触发事件的元素执行顺序和绑定顺序相关,与事件流无关。

你可能感兴趣的:(javaScript,前端)