【轉載】事件流模型
阿新 • • 發佈:2018-12-23
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"。