事件冒泡的原理?如何禁止事件冒泡 ?
1.如何阻止事件冒泡?
function stopBubble(e){
//如果提供了事件物件,則這是一個非 ie 瀏覽器
if(e && e.stopPropagation){
e.stopPropagation();
}else{
window.event.cancelBubble = true;
}
return false;
}
2.事件流
事件流描述的是從頁面中接受事件的順序,IE 的事件流是事件冒泡,而 Netscape Communicator 的事件流是事件捕獲流。
事件冒泡:即事件開始時由最具體的元素,然後逐級向上傳播到較為不具體的結點。(ie
ff
、chrome
、safari
會將事件一直冒泡到 window
物件。)
事件捕獲:事件捕獲的思想是不太具體的結點應該更早接收到事件,而最具體的結點應該最後接受到事件。事件捕獲的用意在於在事件達到預定目標之前捕獲它。
要阻止特定事件的預設行為,可以使用 preventDefault()
方法。例如,連結的預設行為就是在被單擊時會導航到其 href
特性指定的 URL。如果你想阻止連結導航這一預設行為,那麼通過連結的onclick
事件處理程式可以取消它:
var link = document.getElementById("myLink");
link.onclick = function (event){
event.preventDefault();
};
只有 cancelable
屬性設定為 true
的事件,才可以使用 preventDefault()
來取消其預設行為。
stopPropagation()
方法用於立即停止事件在 DOM 層次中的傳播,即取消進一步的事件捕獲或冒泡。例如,直接新增一個按鈕的事件處理給程式可以呼叫 stopPropagetion()
,從而避免觸發註冊在 document.body
上面的事件處理程式:
var btn = document.getElementById("myBtn");
btn.onclick = function (event){
alert("Clicked");
event.stopPropagation();
};
document.body.onclick = function(event){
alert("Body clicked");
};
事件物件的 eventPhase
屬性,可以用來確定事件當前正位於事件流的哪個階段。如果是在捕獲階段呼叫的事件處理程式,其值為1
;如果事件處理程式處於目標物件上,其值為2
;如果是在冒泡階段呼叫的事件處理程式,其值為3
。這裡要注意的是,儘管“處於目標”發生在冒泡階段,但是 eventPhase 的值仍然一直等於2
。
var btn = document.getElementById("myBtn");
btn.onclick = function(event){
alert(event.eventPhase);//2
}
document.body.addEventListener("click",function(evnet){
alert(event.eventPhase);//1
},true);
document.body.onclick = function(event){
alert(event.eventPhase);//3
}
當單擊這個例子中的按鈕時,首先執行的事件處理程式是在捕獲階段觸發的新增到 document.body
中的那一個,結果會彈出一個警告框表示 event.Phase
的值為1
。接著,會觸發在按鈕上註冊的事件處理程式,此時的 eventPhase
的值為2
;最後一個被觸發的事件處理程式,是在冒泡階段執行的新增到 document.body
上的那一個,顯示 eventPhase
的值為3
。而當 eventPhase
的值為2
時,this.target
和 currentTarget
的值始終都是相等的。
只有在事件處理程式執行期間,event
物件才會存在;一旦事件處理程式執行完成,event
物件就會被銷燬。