事件捕获和事件冒泡
我们先写一段代码,爷爷嵌套爸爸,爸爸再嵌套儿子,再给他们添加相应的点击事件
<!-- HTML -->
<div id="grand">
<div id="father">
<div id="child"></div>
</div>
</div>
// CSS
div#grand{
background-color: red;
width: 500px;
height: 500px;
}
div#father{
background-color: green;
width: 400px;
height: 400px;
}
div#child{
background-color: yellow;
width: 200px;
height: 200px;
}
var div = document.getElementsByTagName("div");
div[0].addEventListener('click',function(){
console.log("爷爷被点了");
},false);
div[1].addEventListener('click',function(){
console.log("爸爸被点了");
},false);
div[2].addEventListener('click',function(){
console.log("儿子被点了");
},false);
点最里面的儿子
为什么爸爸和爷爷都被点了?
其实这就涉及到了事件冒泡和捕获
先来看张图
image.png
我来简单模拟一下儿子被点击后发生了什么:
- (从左边的捕获阶段开始)首先问爷爷,你的孙子被点了,你有没有事件响应一下,然后再问爸爸,你的儿子被点了,你有没有事件响应一下,最后再问儿子自己,你被点了,有没有事件响应一下。这个阶段叫捕获阶段。
- 这一个阶段问完之后,从儿子开始往上又重复一次,问爸爸,再问爷爷,这就是DOM事件流。这个阶段叫冒泡阶段。
- (其实爷爷上面还有body,document,window,这里为了方便理解就没有列出)
简单下个定义,事件冒泡就是:从你点击的那个元素开始,逐级往上直到window,检查是否有冒泡阶段的执行事件
事件捕获就是:点击内层元素,从最外围的window逐级往内直到被点击的元素,检查是否有捕获阶段的执行事件
注:事件冒泡和捕获不单单只是点击事件才有,这里只是拿点击事件举例
那问题来了,我上面给爷爷爸爸添加的点击事件,我怎么知道是捕获阶段的还是冒泡阶段的呢?
答案就是:
addEventListener的第三个参数,填true,绑定的事件就是捕获阶段的,填false或不填,就是冒泡阶段的。
再看这个图 是不是清晰多了 image.png
事件流就是先进行捕获阶段的询问,有则响应,然后再进行冒泡阶段的询问,有则执行!
假如爸爸或爷爷身上既有冒泡阶段的事件,又有捕获阶段的事件,根据事件流的规则,是先执行捕获的,等到冒泡到爷爷身上才执行冒泡阶段的!
特例:假如被点击的那个元素身上有冒泡和捕获事件,按照代码顺序执行!(也就是说被点击的元素身上没有先捕获后冒泡的顺序之分)
放一段代码
var div = document.getElementsByTagName("div");
div[0].addEventListener('click',function(){
console.log("爷爷冒泡");
},false);
div[0].addEventListener('click',function(){
console.log("爷爷捕获");
},true);
div[1].addEventListener('click',function(){
console.log("爸爸冒泡");
},false);
div[1].addEventListener('click',function(){
console.log("爸爸捕获");
},true);
div[2].addEventListener('click',function(){
console.log("儿子冒泡");
},false);
div[2].addEventListener('click',function(){
console.log("儿子捕获");
},true);
点击儿子,看看控制台的打印结果
image.png好了,故事讲完了。
网友评论