浅析Javascript中的冒泡机制

气泡会从水底向上移动到水面,这就是冒泡。Javascript中的冒泡机制就是将事件当作气泡,由内而外冒出去。

1、事件的发生过程

一个事件从发生到执行有三个过程:

1.事件的捕获阶段:从外到内

2.事件的目标阶段:目标元素本身

3.事件的冒泡阶段:从内向外

为了解释这个问题,我们来举个例子:

事件触发

当我们点击div2时,首先会进入事件的捕获阶段:

先由外到里来找事件的真正触发者,操作系统–>对应应用程序–>window–>body–>div1–>div2;

再到事件的第二阶段:确定事件的真正触发者是div2;

最后来到事件的冒泡阶段:由内向外传递事件(顺序与捕获阶段相反)和真正触发者对象(后文简称为 触发对象),执行div2中的onclick事件后,在向他的父亲元素传递事件和对象,若父亲元素存在onclick事件则执行;再继续向上传递事件和对象,以此内推知道无父亲元素为止。

注:关于事件的捕获阶段和事件的冒泡阶段可以用以下函数来模拟

1
2
3
// 目标元素. addEventListener(操作,绑定的函数,boolean);
element.addEventListener('click',function(){},true); //捕获阶段
element.addEventListener('click',function(){},false); //冒泡阶段

要切实说明这个问题,我们来看一个例子:

css代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#red {
width: 400px;
height: 400px;
background-color: red;
}
#yellow {
width: 300px;
height: 300px;
background-color: yellow;
}
#blue {
width: 200px;
height: 200px;
background-color: blue;
}

HTML代码如下:

1
2
3
4
5
<div id="red">
<div id="yellow">
<div id="blue"></div>
</div>
</div>

Javascript代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var red = GEBID$('red');
var yellow = GEBID$('yellow');
var blue = GEBID$('blue');

blue.onclick = function(e){ //这里的 e 便是触发事件(点击事件)
console.log('蓝色');
console.log(e.target); //e.target 触发事件的对象元素(触发对象)
}

/*yellow.onclick = function(e){
console.log('黄色');
console.log(e.target);
}*/

red.onclick = function(e){
console.log('红色');
console.log(e.target);
}

界面预览

当我们点击blue时,bule的onclick被触发,查看blue中是否有onclik事件,若有则执行输出语句,执行结束后会根据冒泡机制向上一层传递事件和触发对象至yellow,但此时yellow中并未绑定onclick事件,所以不执行输出语句,继续向上传递;到red后,由于red绑定了onclick事件,则执行输出语句;在传递给body……控制台结果如下:

执行结果

我们发现:虽然red也执行了它自身的事件函数,但是触发对象却仍然是blue。这是因为虽然我们没有点击red,但是我们点击了blue,而blue会将这一点击信号通过冒泡机制向上传递,传递过程中只要遇到绑定有onclick事件的元素便会触发其事件函数,但这沿路走过的一直都是我们最初所点击的那位始作俑者。

值得注意的是:

1.当我们点击blue而触发事件,并引发冒泡机制后,yellow和red所执行的 element.onclick = function(e){} 中的e所代表的事件是同一个事件,是由blue通过冒泡机制传递过来的。

2.只要没有阻止冒泡机制或者说冒泡机制生效,无论当前元素是否绑定onclick事件,它都会向上传递点击事件。

2、如何阻止冒泡机制

当我们需要点击blue而不触发其祖先元素的事件时,我们只需要在blue的事件函数中加入以下代码即可(已做了兼容性处理)

1
2
3
4
5
6
7
8
9
function stopBubble(e) { 
//如果提供了事件对象,则这是一个非IE浏览器
if ( e && e.stopPropagation )
//因此它支持W3C的stopPropagation()方法
e.stopPropagation();
else
//否则,我们需要使用IE的方式来取消事件冒泡
window.event.cancelBubble = true;
}

使用示例:

1
2
3
4
5
blue.onclick = function(e){ 
console.log('蓝色');
console.log(e.target);
function stopBubble(e); //断开冒泡机制链 使得事件不会继续向上传递
}

最后更新: 2019年04月19日 18:47

原始链接: https://HowlCN.github.io/2019/05/06/浅析Javascript中的冒泡机制/

× 请我吃糖~
打赏二维码