1.事件冒泡的机制:在元素(标签)嵌套中,如果这些标签都注册了同一个事件,那么在触发内部标签的该事件时,外部标签的该事件也会被触发。事件冒泡这个机制不会触发到内部的元素事件,只会影响到外部的元素事件。这个机制是普遍存在的!
HTML代码
<div id="dv1"> <div id="dv2"> <div id="dv3"></div> </div> </div>
CSS代码
#dv1{ 300px; height: 300px; background-color: pink; } #dv2{ 200px; height: 200px; background-color: skyblue; } #dv3{ 100px; height: 100px; background-color: yellow; }
JS代码
var dvObj = [document.getElementById("dv1"),document.getElementById("dv2"),document.getElementById("dv3")]; function fn2(){ //一个事件处理函数,在控制台写入触发对象的id console.log(this.id); } for (var i = 0; i < dvObj.length; i++) { //循环注册点击事件 dvObj[i].addEventListener("click", fn2, false); }
在点击内部盒子时外部的盒子点击事件也会被触发---这就是事件冒泡
2.如何阻止事件冒泡?
(1).在事件处理函数内部添加 window.event.cancelBubble = true; 用于IE8
(2).在事件处理函数的形参列表中加入一个参数(事件处理函数默认的参数对象)然后函数内加入 参数名.stopPropagation(); 谷歌、火狐以及现版本大多浏览器
function fn2(e){ //一个事件处理函数,在控制台写入触发对象的id console.log(this.id); e.stopPropagation(); //e这个形参是事件处理函数的一个默认参数,e.stopPropagation()这个方法是谷歌和火狐浏览器的阻止冒泡机制的方法 // window.event.canceBubble = true;//这是IE8特有的阻止冒泡的方法 } for (var i = 0; i < dvObj.length; i++) { //循环注册点击事件 dvObj[i].addEventListener("click", fn2, false); }
3.
事件触发的三个方式: 1.事件捕获方式 2.事件目标方式 3.事件冒泡方式
事件可以由这三种方式触发,事件捕获方式和事件冒泡方式都基于事件冒泡机制:
- 1.由事件捕获方式触发:由外向内的传递方式触发事件
- 2.事件目标方式触发:不是由于冒泡机制引发的事件,即事件触发的基点对象,他的事件触发方式为事件目标方式
- 3.由冒泡方式触发:由内向外的传递方式触发事件
注意:事件触发方式里的冒泡方式和冒泡机制做出区分:事件冒泡机制是一直存在的,不管是设置addEventListener方法里的布尔值为true还是false,都存在冒泡机制,内部元素的事件触发都会引起外部元素的事件触发。冒泡机制的阻止是靠上面2里所述的方法。
事件触发方式的冒泡和捕获只是决定事件触发的先后顺序,可以用设置事件方法里的布尔值来设置。
这里就可以说明addEventListener方法里的布尔值的作用:控制事件处理函数的传递方式:false-事件冒泡方式;true-事件捕获方式
下面设置布尔值为false查看结果:
var dvObj = [document.getElementById("dv1"),document.getElementById("dv2"),document.getElementById("dv3")]; function fn2(){ //一个事件处理函数,在控制台写入触发对象的id console.log(this.id); } for (var i = 0; i < dvObj.length; i++) { //循环注册点击事件 dvObj[i].addEventListener("click", fn2, false); } //点击内部盒子,输出结果为dv3,dv2,dv1;可以看出里面的盒子的事件先触发,由冒泡方式内向外依次触发冒泡机制引发的事件
下面设置布尔值为true查看结果:
var dvObj = [document.getElementById("dv1"),document.getElementById("dv2"),document.getElementById("dv3")]; function fn2(){ //一个事件处理函数,在控制台写入触发对象的id console.log(this.id); } for (var i = 0; i < dvObj.length; i++) { //循环注册点击事件 dvObj[i].addEventListener("click", fn2, true); } //点击内部盒子,输出结果为dv1,dv2,dv3;可以看出外面的盒子的事件先触发,由捕获方式由外向里依次触发冒泡机制引发的事件
可以利用:事件处理参数.eventPhase查看事件触发的方式:1为事件捕获,2为事件目标,3为事件冒泡
例
var dvObj = [document.getElementById("dv1"),document.getElementById("dv2"),document.getElementById("dv3")]; function fn2(e){ console.log(this.id + "触发方式为" + e.eventPhase); } for (var i = 0; i < dvObj.length; i++) { dvObj[i].addEventListener("click", fn2, true); }
点击内部盒子结果为:
dv1触发方式为1
dv2触发方式为1
dv3触发方式为2
可以看出这是捕获方式,dv1先触发,然后向内,dv2也是捕获方式,再向内到达目标元素,为目标方式
将true改成false同理,可以看出除目标元素之外其他元素的触发是冒泡方式