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>

冒泡部分

var $input = document.getElementsByTagName("input")[0];
var $div = document.getElementsByTagName("div")[0];
var $body = document.getElementsByTagName("body")[0];
       
$input.onclick = function(e){
    this.style.border = "5px solid red"
     var e = e || window.e;
    alert("red");
}
 $div.onclick = function(e){
     this.style.border = "5px solid green";
     alert("green");
 }
 $body.onclick = function(e){
    this.style.border = "5px solid yellow";
    alert("yellow");
 }
 
//依次彈出”red“,"green","yellow"

你的本意是觸發button這個元素,卻連同父元素繫結的事件一同觸發。這就是事件冒泡。

如果對input的事件繫結改為
$input.onclick = function(e){
    this.style.border = "5px solid red"
    var e = e || window.e;
    if (e && e.stopPropagation){
        e.stopPropagation();//阻止事件冒泡
    }else{
        e.cancelBubble=true;//IE
    }      
}
 
//這個時候只會彈出”red“,因為阻止了事件冒泡。

捕獲部分

$input.addEventListener("click", function(){
    this.style.border = "5px solid red";
    alert("red");
}, true)
$div.addEventListener("click", function(){
    this.style.border = "5px solid green";
    alert("green");
}, true)
$body.addEventListener("click", function(){
    this.style.border = "5px solid yellow";
    alert("yellow");
}, true)
  
//這個時候依次彈出”yellow“,"green","red"。
  
//這就是事件的捕獲。
//如果把addEventListener方法的第三個引數改成false,則表示只在冒泡的階段觸發,彈出的依次為:”red“,"green","yellow"。