HTML

[HTML] target phase事件顺序

2016-07-31  本文已影响135人  何幻

我们知道addEventListener的第三个参数,
useCapture用来标识该事件监听函数用于处理什么阶段的事件。
不写useCapture,或者useCapture=false,表示用于处理冒泡阶段的事件,
useCapture=true,表示用于处理捕获阶段的事件。


可是,关于事件与事件监听函数目标阶段的事件顺序,还有值得注意的地方,

<div id="div1">
    <input id="button1" type="button" value="test">
</div>

<script>
    var btn=document.querySelector('#button1');
    var div=document.querySelector('#div1');

    div.addEventListener('click',function(e){
        console.log(1,e.target,e.currentTarget);
    },false);

    btn.addEventListener('click',function(e){
        console.log(2,e.target,e.currentTarget);
    },false);

    btn.addEventListener('click',function(e){
        console.log(3,e.target,e.currentTarget);
    },true);

    btn.addEventListener('click',function(e){
        console.log(4,e.target,e.currentTarget);
    },false);

    div.addEventListener('click',function(e){
        console.log(5,e.target,e.currentTarget);
    },true);
</script>

运行结果如下:

5 <input id=​"button1" type=​"button" value=​"test">​ <div id=​"div1">​…​</div>​
2 <input id=​"button1" type=​"button" value=​"test">​ <input id=​"button1" type=​"button" value=​"test">​
3 <input id=​"button1" type=​"button" value=​"test">​ <input id=​"button1" type=​"button" value=​"test">​
4 <input id=​"button1" type=​"button" value=​"test">​ <input id=​"button1" type=​"button" value=​"test">​
1 <input id=​"button1" type=​"button" value=​"test">​ <div id=​"div1">​…​</div>​

我们看到,
div上在捕获阶段的事件监听函数是最先被调用的(5号),
随后按注册顺序调用了btn上目标阶段的事件监听函数(2,3,4号),
最后调用了div上冒泡阶段的事件监听函数(1号)。


(1)关于事件和事件监听函数是其中一个容易引起混淆的点,
当我们点击btn,准备触发btn上名为click的事件时,
无论btn的祖先和btn上是否注册了事件监听函数,click事件都会在它们上面触发的
只不过如果没有注册事件监听函数,就忽略处理click事件罢了。
因此,body上的,html上的click事件(包括冒泡和捕获)实际上也是触发了的。

(2)另外一个点是,事件发生实际上包含了3个阶段,捕获阶段(capture phase),目标阶段(target phase)和冒泡阶段(bubble phase)。
人们提及捕获阶段和冒泡阶段较多,容易忽略目标阶段。
事实上,目标阶段事件监听函数的调用顺序与注册顺序有关。

Next, the implementation must determine the current target's candidate event listeners. This must be the list of all event listeners that have been registered on the current target in their order of registration.

因此,目标阶段的2,3,4号事件监听函数会按注册顺序调用,
不是先调用useCapture=true的事件监听函数,再调用useCapture=false事件监听函数。
useCapture只对捕获和冒泡阶段有用,对目标阶段无效。


参考
DOM 3 Events : Event Flow

上一篇下一篇

猜你喜欢

热点阅读