Mozilla浏览器提供了一个JavaScript的绑定事件监听器的函数addEventListener
document.getElementById("button1").addEventListener("click",callback,isCapture);
其中各个参数说明如下:
- "click" 代表注册的什么事件。“click”代表的自然是点击事件,注意前面不加“on”前缀。也可以是其他事件,去掉“on”前缀即可。
- callback 回调函数,当事件被触发时调用该函数。
- isCapture 是否在捕获阶段执行回调。默认为false。
下面来说一下第三个参数 isCapture。它是一个boolean类型的值。说到它就不得不提一下JavaScript中的事件触发经历的两个阶段:捕获阶段和冒泡阶段。
从图中可见都是嵌套关系。我们假定点击了最内层的text元素,触发了它的onclick事件。
但是实际上因为是嵌套的原因,点击了最内层的text也相当于点击了它的父元素div,也相当于点击了父元素的父元素body……也相当于点击了window,那么如果这些外层元素也有onclick的点击事件,它们也应当被触发,现在的问题是,是在什么时候被触发?
图中可见有两个阶段
- 先从最外面开始(也就是window开始)向内推进,直到定位到触发的元素text。这一过程叫“捕获过程”。
- 然后从该元素开始,又向上级冒泡。该过程为“冒泡过程”。
显然,对于这个嵌套链上的每个元素,它的触发按数即可以在捕获阶段被执行,也可以在冒泡阶段被执行。
所以,addEventListener的第三个参数正是指定这个触发时段的。默认情况是false,也就是在冒泡阶段被执行;如果指派为true,则在捕获阶段被执行。
用一个简单的实验可以说明问题:
假设现在一个HTML界面有三个呈嵌套关系的元素
<div id="outer" >
<div id="middle" >
<input type="button" id="inner" value="inner"/>
</div>
</div>
最外层是outer,中间是middle,内部是inner。
下面是三个元素绑定点击事件:
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。