1. 程式人生 > >事件冒泡的原理?如何禁止事件冒泡 ?

事件冒泡的原理?如何禁止事件冒泡 ?

1.如何阻止事件冒泡?

function stopBubble(e){
    //如果提供了事件物件,則這是一個非 ie 瀏覽器
    if(e && e.stopPropagation){
        e.stopPropagation();
    }else{
        window.event.cancelBubble = true;
    }
    return false;
}

2.事件流

事件流描述的是從頁面中接受事件的順序,IE 的事件流是事件冒泡,而 Netscape Communicator 的事件流是事件捕獲流。

事件冒泡:即事件開始時由最具體的元素,然後逐級向上傳播到較為不具體的結點。(ie

ffchromesafari會將事件一直冒泡到 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.targetcurrentTarget 的值始終都是相等的。

只有在事件處理程式執行期間,event 物件才會存在;一旦事件處理程式執行完成,event 物件就會被銷燬。