1. 程式人生 > >js 事件冒泡與事件捕獲

js 事件冒泡與事件捕獲

nodename 瀏覽器兼容 而不是 rop 希望 bubble lis 彈出 element

一、事件冒泡

事件冒泡是指在事件發生過程中先從目標節點開始執行,並一層一層的相父節點依次查詢直到document,並執行相同事件的過程。

 btn1.addEventListener(‘click‘,function(e){
        //true 為事件捕獲,false 為事件冒泡
        //false為默認方式,冒泡方式執行
        //點擊btn1時,如果是事件冒泡,則先執行btn1上的click事件,然後執行父元素div1上的click事件
        //如果是事件捕獲,則先執行父元素上的click事件,然後執行btn1上的click事件
        var e= e||window.event;
        alert(
‘你點擊了btn1‘); },false);
div1.addEventListener(‘click‘,function(e){

alert(‘你點擊了div1‘);
},false);
 

這樣的寫法,當你點擊btn1的時候,先彈出“你點擊了btn1”,然後彈出“你點擊了div1”;

二、事件捕獲

事件捕獲就是在事件發生過程中,先從document開始執行相同的事件,依次一層一層查找到目標節點,然後執行相同的事件。

btn1.addEventListener(‘click‘,function(e){
        //true 為事件捕獲,false 為事件冒泡
        //
false為默認方式,冒泡方式執行 //點擊btn1時,如果是事件冒泡,則先執行btn1上的click事件,然後執行父元素上的click事件 //如果是事件捕獲,則先執行父元素上的click事件,然後執行btn1上的click事件 var e= e||window.event; alert(‘你點擊了btn1‘); },true); div1.addEventListener(‘click‘,function(e){ alert(‘你點擊了div1‘); },true);

這樣的寫法,當你點擊btn1的時候,先彈出“你點擊了div1”,然後彈出“你點擊了btn1”;

三、阻止事件冒泡和事件捕獲

在阻止事件冒泡和捕獲方式上,IE和其他瀏覽器不同;

首先是event的不同;

Event 對象代表事件的狀態,比如事件在其中發生的元素、鍵盤按鍵的狀態、鼠標的位置、鼠標按鈕的狀態。

事件通常與函數結合使用,函數不會在事件發生前被執行!

在IE中輸出的event 為 event;event在IE中為全局函數,可以在任何地方調用。

在FF中輸出的為event; 在FF中只能在實踐中調用,把event作為參數傳進函數內

其他瀏覽器 則為二者都可以;

所以在確定event的時候需要進行瀏覽器兼容

 var e = event||window.event;

等同於 e = e?event:window.event;

通過這種方法,IE識別event,其他瀏覽器識別window.event;

在阻止事件方法上也有不同

IE:e.cancelBubble = true; 通過把e.cancelBubble設置為true,來阻止事件分發;

標準瀏覽器:e.stopPropagation(); 標準瀏覽器的stopPropagation 方法可以設置不再派發事件。

兼容代碼如下:

    var e = event||window.event;
        if(e.stopPropagation){
            e.stopPropagation();//標準瀏覽器
        }else{
            e.cancelBubble = true;//IE瀏覽器
        }

四、事件委托方法依托事件冒泡機制

傳統事件綁定

我們給每一個li綁定點擊之後背景顏色變紅的事件;

var uli = document.getElementById(‘uli‘);
    var lis = uli.getElementsByTagName(‘li‘);
    for (var i = 0;i<lis.length;i++){
        lis[i].onclick = function(){
           this.style.backgroundColor = ‘red‘;
        }
    }
    //這樣我們就可以做到li上面添加鼠標事件。
    //但是如果說我們可能有很多個li用for循環的話就比較影響性能。

一個事件委托實例

html不變,只更改事件綁定的方法

 var uli = document.getElementById(‘uli‘);
    uli.addEventListener(‘click‘,function(event){
        var e = event||window.event;

        var target = e.target||e.srcElement;//該方法用於查詢發生event事件的具體節點。
        //e.target  是標準瀏覽器的方法
        //e.srcElement 是IE中的方法
        if (target.nodeName.toUpperCase()==‘LI‘){
            target.style.backgroundColor = ‘red‘;
        }
    });

標準瀏覽器查詢event節點的方法是:window.event.target;

IE瀏覽器查詢event節點的方法是:event.srcElement;

這樣的寫法可以在點擊li的時候向上冒泡至ul,然後執行ul上的綁定事件,這樣就不用給每個li都綁定一個點擊事件.

而且新添加的li元素也可以綁定這樣的事件,不用重新綁定

可以用removeElementListener 來取消綁定的事件函數

五、綁定事件監聽方法

傳統綁定事件

on + click、mouseover、keyup 等

傳統綁定的

優點

  • 非常簡單和穩定,可以確保它在你使用的不同瀏覽器中運作一致
  • 處理事件時,this關鍵字引用的是當前元素,這很有幫助

缺點

綁定同樣事件的多個函數會覆蓋,只能觸發最後一種。

uli.onclick = function(){

  alert(‘1‘);

}

uli.onclick = function(){

  alert(‘2‘);

}

這樣的寫法執行時只能執行alert(‘2‘); 解除綁定用 uli.onclick = null;

W3C綁定事件

uli.addEventListener(‘click‘,function(){.........},false);

  1. W3C綁定的優點
    • 該方法同時支持事件處理的捕獲和冒泡階段。事件階段取決於addEventListener最後的參數設置:false (冒泡) 或 true (捕獲)。
    • 在事件處理函數內部,this關鍵字引用當前元素。
    • 事件對象總是可以通過處理函數的第一個參數(e)捕獲。
    • 可以為同一個元素綁定你所希望的多個事件,同時並不會覆蓋先前綁定的事件
  2. W3C綁定的缺點
    • IE不支持,你必須使用IE的attachEvent函數替代。

解除綁定用 removeEventListener(‘click‘,fucntion(){.........});

IE綁定事件

IE用attachEvent方法綁定事件

element.attachEvent(‘onclick‘, function(){
        // ...
    });
  1. IE方式的優點
    • 可以為同一個元素綁定你所希望的多個事件,同時並不會覆蓋先前綁定的事件。
  2. IE方式的缺點
    • IE僅支持事件捕獲的冒泡階段
    • 事件監聽函數內的this關鍵字指向了window對象,而不是當前元素(IE的一個巨大缺點)
    • 事件對象僅存在與window.event參數中
    • 事件必須以ontype的形式命名,比如,onclick而非click
    • 僅IE可用。你必須在非IE瀏覽器中使用W3C的addEventListene

解除綁定函數用 detachEvent(‘onclick‘,fucntion(){})

js 事件冒泡與事件捕獲