Featured image of post 关于 JavaScript 的 addEventListener 函数第三个参数的作用

关于 JavaScript 的 addEventListener 函数第三个参数的作用

Mozilla 浏览器提供了一个 JavaScript 的绑定事件监听器的函数 addEventListener

1
document.getElementById("button1").addEventListener("click",callback,isCapture);

其中各个参数说明如下:

  • click 代表注册的什么事件。“click”代表的自然是点击事件,注意前面不加“on”前缀。也可以是其他事件,去掉“on”前缀即可。
  • callback 回调函数,当事件被触发时调用该函数。
  • isCapture 是否在捕获阶段执行回调。默认为 false。

下面来说一下第三个参数 isCapture。它是一个 boolean 类型的值。说到它就不得不提一下 JavaScript 中的事件触发经历的两个阶段:捕获阶段和冒泡阶段。

事件触发经历的两个阶段

从图中可见都是嵌套关系。我们假定点击了最内层的 text 元素,触发了它的 onclick 事件。 但是实际上因为是嵌套的原因,点击了最内层的 text 也相当于点击了它的父元素 div,也相当于点击了父元素的父元素 body……也相当于点击了 window,那么如果这些外层元素也有 onclick 的点击事件,它们也应当被触发,现在的问题是,是在什么时候被触发? 图中可见有两个阶段

  1. 先从最外面开始(也就是 window 开始)向内推进,直到定位到触发的元素 text。这一过程叫“捕获过程”。
  2. 然后从该元素开始,又向上级冒泡。该过程为“冒泡过程”。

显然,对于这个嵌套链上的每个元素,它的触发按数即可以在捕获阶段被执行,也可以在冒泡阶段被执行。

所以,addEventListener 的第三个参数正是指定这个触发时段的。默认情况是 false,也就是在冒泡阶段被执行;如果指派为 true,则在捕获阶段被执行。

用一个简单的实验可以说明问题: 假设现在一个 HTML 界面有三个呈嵌套关系的元素

1
2
3
4
5
 <div id="outer" >
    <div id="middle" >
      <input type="button" id="inner" value="inner"/>
    </div>
 </div>

最外层是 outer,中间是 middle,内部是 inner。 下面是三个元素绑定点击事件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
window.onload=function(){ 
    document.getElementById("inner").addEventListener("click",show("inner"),false); 
    document.getElementById("middle").addEventListener("click",show("middle"),false); 
    document.getElementById("outer").addEventListener("click",show("outer"),false); 
} 
function show(i){ 
    return function(){
        console.log(i);
    }
} 

点击对应元素,就会在控制台打印出相应信息。下面分别修改三个 boolean 参数,观察输出结果

输出结果

OUTPUT 的结果左边先打印,右边后打印。我们举两个结果说明:

  • isCapture 分别被设置为 TFF 的时候,点击最内层 inner 的按钮,由于 outer、middle 设置的为 false,那么它们在捕获阶段不会被触发,控制流到达 inner,此时先输出 inner,然后开始返回,也就是向上级冒泡,所以依次触发 middle、outer。
  • isCapture 分别被设置为 TTF 的时候,点击最内层 inner 按钮,由于 outer 设置为 false,那么它在进入的阶段不会被触发,但是当遇到 middle 时候,因为是 true,所以会被触发,先输出 middle,然后输出 inner,最后在返回的冒泡阶段,outer 被触发,最后输出 outer。

参考

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Built with Hugo
主题 StackJimmy 设计