先贴代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>冒泡</title> <style> #a{ width: 300px; height:300px; background-color: cadetblue; } #b{ width: 200px; height:200px; background-color: chocolate; } #c{ width: 100px; height:100px; background-color: coral; } </style> </head> <body> <div id="a"> <div id="b"> <div id="c"></div> </div> </div> <script src="mainx.js"></script> </body> </html>
/** * Created by Administrator on 2016/8/10. */ (function () { var a=document.getElementById("a"); var b=document.getElementById("b"); var c=document.getElementById("c"); a.addEventListener("click",function () { console.log("a is clicked"); }); b.addEventListener("click",function () { console.log("b is clicked"); }); c.addEventListener("click",function () { console.log("c is clicked"); }); })();
运行结果如图:
当点击最小块c的时候,a和b也会被点击。也就导致了所谓的冒泡。
当js代码修改为
/** * Created by Administrator on 2016/8/10. */ (function () { var a = document.getElementById("a"); var b = document.getElementById("b"); var c = document.getElementById("c"); a.addEventListener("click", function () { console.log("a is clicked"); }); b.addEventListener("click", function () { console.log("b is clicked"); }); c.addEventListener("click", function (event) { console.log("c is clicked"); event.stopPropagation(); }); })();
结果为:
当点击c后,只有c被点击
stopPropagation()方法会阻止冒泡行为。
当代码再次修改为:
/** * Created by Administrator on 2016/8/10. */ (function () { var a = document.getElementById("a"); var b = document.getElementById("b"); var c = document.getElementById("c"); a.addEventListener("click", function () { console.log("a is clicked"); }); b.addEventListener("click", function () { console.log("b is clicked"); }); c.addEventListener("click", function (event) { console.log("c is clicked"); event.stopPropagation(); }); c.addEventListener("click",function () { console.log("c1 is clicked"); }); })();
结果为:
当点击C的时候,两个事件都会触发。
在修改代码为:
/** * Created by Administrator on 2016/8/10. */ (function () { var a = document.getElementById("a"); var b = document.getElementById("b"); var c = document.getElementById("c"); a.addEventListener("click", function () { console.log("a is clicked"); }); b.addEventListener("click", function () { console.log("b is clicked"); }); c.addEventListener("click", function (event) { console.log("c is clicked"); event.stopPropagation(); event.stopImmediatePropagation(); }); c.addEventListener("click", function (event) { console.log("c1 is clicked"); }); })();
结果为:
又变为只触发一个事件了。
stopImmediatePropagation()方法,只阻止父类,不阻止兄弟事件。(这里写错了,他也阻止了兄弟事件!!!!!!!!!!!!!!!!!!!!!!!!(剁手))
冒泡告一段落
开始讲三个阶段:
事件的三个阶段:捕获,目标,冒泡。
捕获阶段:从外到内,监听中设置为true,子类事件不产生
目标阶段:点击的目标
冒泡阶段:从内到外
先贴代码:
/** * Created by Administrator on 2016/8/10. */ (function () { var a = document.getElementById("a"); var b = document.getElementById("b"); var c = document.getElementById("c"); a.addEventListener("click", function () { console.log("冒泡阶段的a is clicked"); }); b.addEventListener("click", function () { console.log("冒泡阶段的b is clicked"); }); // c.addEventListener("click", function (event) { // console.log("c is clicked"); // // event.stopPropagation(); // event.stopImmediatePropagation(); // }); c.addEventListener("click", function (event) { console.log("目标阶段的c is clicked"); }); b.addEventListener("click",function (event) { console.log("捕获阶段的b is clicked"); },true); a.addEventListener("click",function () { console.log("捕获阶段的a is clicked"); },true); })();
执行结果为:
执行顺序如图:先捕获,后目标,在冒泡。也可理解为,从外到内,在从内到外。
另外,可以用event.eventPhase去测试是什么阶段,
捕获阶段,返回值为1
目标阶段,返回值为2
冒泡阶段,返回值为3
自己的理解:
用法,还没用到,以后补充(⊙﹏⊙)b;
阻止冒泡的好处,防止子元素的父类元素被点击而触发子类事件。
设置捕获的好处(设置,末尾true属性),可以是冒泡事件反向执行。
补充一点2016-10-28 11:08:55(感谢 "潘多拉之欣" 的提醒)
关于stopImmediatePropagation和stopPropagation的区别
网上大神的解释