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"。