假设有这么一段代码javascript
<body> <div><p>标签</p> </div> </body>
转换成图以下html
咱们知道Dom是有节点关系的java
body -> div -> p 之间的关系就是 爷爷 -> 父亲 -> 儿子。
咱们来思考一个关键的问题浏览器
若是此时咱们在 body div p 都绑定一个点击事件(click)。此时若是咱们只点击 p标签,它会不会触发div绑定事件 和 body绑定事件?this
答案是会的3d
那这个时候就会有一个问题,既然点击 p标签 会触发 div绑定事件 和 body绑定事件,那执行顺序是怎么样的呢?code
body事件 -> div事件 -> p事件? 仍是 p事件 -> div事件 -> body事件?
这两种不一样的执行顺序就是对应上面的 事件冒泡 和 事件捕获。htm
事件捕获
事件从最上一级标签开始往下查找,直到捕获到事件目标(body事件 -> div事件 -> p事件)。对象
事件冒泡
事件从事件目标开始,往上冒泡直到页面的最上一级标签( p事件 -> div事件 -> body事件)blog
为了避免混淆记忆它们,这里有个通俗的理解冒泡:
冒泡嘛,就像水里往上冒的泡泡,从一开始很小,而后慢慢变大直到破裂。因此是从小到大,也就是子标签到父标签传递的过程。那么事件捕获记住与冒泡相反就能够了。
代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件冒泡</title> <style> #dv1{ /*为了直观 这里添加些样式*/ width: 300px; height: 200px; background-color: red; } #dv2{ width: 250px; height: 150px; background-color: green; } #dv3{ width: 200px; height: 100px; background-color: blue; } </style> </head> <body> <div id="dv1">爷爷 <div id="dv2">父亲 <div id="dv3">儿子</div> </div> </div> <script> //事件冒泡:多个元素嵌套,有层次关系,这些元素都注册了相同的事件,若是里面的元素的事件触发了,外面的元素的该事件自动的触发了. document.getElementById("dv1").onclick=function () { console.log(this.id+" 爷爷"); }; document.getElementById("dv2").onclick=function () { console.log(this.id+" 父亲"); }; //事件处理参数对象 document.getElementById("dv3").onclick=function (e) { console.log(this.id+" 儿子"); //阻止事件冒泡 //e.stopPropagation(); }; </script> </body> </html>
运行结果
从这个示例咱们能够看出3点
一、当点击儿子元素后,父亲和爷爷的点击事件也触发了。 二、onclick事件的顺序 儿子 - 父亲 - 爷爷。 三、当点击爷爷元素后,父亲和儿子的点击是不会触发的。
既然有冒泡事件,那确定在实际开放过程当中,你不须要冒泡,你只想儿子点击触发事件,父亲和爷爷不触发事件。
语法
一、window.event.cancelBubble=true; IE特有的,谷歌支持,火狐不支持 二、e.stopPropagation(); 谷歌和火狐支持
由于我用的是谷歌浏览器,因此这里用第二种方式阻止冒泡(只需把上面阻止事件冒泡的代码取消注释就能够了)
运行结果
从运行结果很明显看出,已经阻止了事件冒泡。
示例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>title</title> <style> #dv1 { width: 300px; height: 200px; background-color: red; } #dv2 { width: 250px; height: 150px; background-color: green; } #dv3 { width: 200px; height: 100px; background-color: blue; } </style> </head> <body> <div id="dv1">爷爷 <div id="dv2">父亲 <div id="dv3">儿子</div> </div> </div> <script> //为每一个元素绑定事件 这里 /** * 捕获时间 从外到里 * 一、 addEventListener不是每一个浏览器都兼容的 * 二、 这里true为事件捕获 false为事件冒泡 */ document.getElementById("dv1").addEventListener("click", function (e) { console.log(this.id+" 爷爷"); }, true); document.getElementById("dv2").addEventListener("click", function (e) { console.log(this.id+" 父亲"); }, true); document.getElementById("dv3").addEventListener("click", function (e) { console.log(this.id+" 儿子"); }, true); </script> </body> </html>
运行
很明显,这里是从外到里执行事件。
你若是愿意有所做为,就必须善始善终。(22)