前续:本文来自于网络文章整理,仅供参考,欢迎纠错指正。
1、DOM同时支持两种事件模型:捕获型事件和冒泡型事件 (有些浏览器不支持捕获 )
eventPhase:调用事件处理的阶段,1捕获,2目标,3冒泡
捕获阶段是由上层元素到下层元素的顺序依次。而冒泡阶段则正相反。如下图:
当事件触发时body会先得到有事件发生的信息,然后依次往下传递,直到到达最详细的元素。这就是事件捕获阶段。
还记得事件注册方法ele.addEventListener(type,handler,flag)吧,Flag是一个Boolean值,true表示事件捕捉阶段执行,false表示事件冒泡阶段执行。
接着就是事件冒泡阶段。从下往上 依次执行事件处理函数(当然前提是当前元素为该事件注册了事件句柄)。
在这个过程中,可以阻止事件的冒泡,即停止向上的传递。
阻止冒泡有时是很有必要的,实例如下:
1 <div> 2 <input type="button" value="测试事件冒泡" /> 3 </div>
2、冒泡部分:
1 var $input = document.getElementsByTagName("input")[0]; 2 var $div = document.getElementsByTagName("div")[0]; 3 var $body = document.getElementsByTagName("body")[0]; 4 5 $input.onclick = function(e){ 6 this.style.border = "5px solid red" 7 var e = e || window.e; 8 alert("red"); 9 } 10 $div.onclick = function(e){ 11 this.style.border = "5px solid green"; 12 alert("green"); 13 } 14 $body.onclick = function(e){ 15 this.style.border = "5px solid yellow"; 16 alert("yellow"); 17 } 18 19 //依次弹出”red“,"green","yellow"
你的本意是触发button这个元素,却连同父元素绑定的事件一同触发。这就是事件冒泡。
如果对input的事件绑定改为:
1 $input.onclick = function(e){ 2 this.style.border = "5px solid red" 3 var e = e || window.e; 4 if (e && e.stopPropagation){ 5 e.stopPropagation();//阻止事件冒泡 6 }else{ 7 e.cancelBubble=true;//IE 8 } 9 } 10 11 //这个时候只会弹出”red“,因为阻止了事件冒泡。
3、捕获部分:
1 $input.addEventListener("click", function(){ 2 this.style.border = "5px solid red"; 3 alert("red"); 4 }, true) 5 $div.addEventListener("click", function(){ 6 this.style.border = "5px solid green"; 7 alert("green"); 8 }, true) 9 $body.addEventListener("click", function(){ 10 this.style.border = "5px solid yellow"; 11 alert("yellow"); 12 }, true) 13 14 //这个时候依次弹出”yellow“,"green","red"。 15 16 //这就是事件的捕获。 17 //如果把addEventListener方法的第三个参数改成false,则表示只在冒泡的阶段触发,弹出的依次为:”red“,"green","yellow"。