JS和JQuery中的事件委託 學習筆記

來源:互聯網
上載者:User

JS和JQuery中的事件委託 學習筆記

事件委託其實並不是一個很進階的技巧,比如在一個頁面裡面,當只存在兩個按鈕的時候,可能你給按鈕添加監聽是這樣的:(本文不考慮瀏覽器安全色性,關於事件的相容性可參考前面的學習筆記)

按鈕1按鈕2
var btn1 = document.getElementById(btn1);var btn2 = document.getElementById(btn2);btn1.addEventListener(click, clickHandler1);btn2.addEventListener(click, clickHandler2);

當按鈕越來越多的時候,甚至到了幾十上百的時候,我相信很少有人會選擇一個一個的添加事件,首先,其實事件處理函數每個都是對象,都會佔用記憶體,建立的越多,記憶體開銷越大,效能越差;其次,大量“重複”性的代碼擁擠在指令碼裡,非常難以維護,也非常難看;還有,添加大量監聽意味著要頻繁訪問DOM元素,延遲整個頁面的訪問時間。
事件委託就是解決這個問題的一個方案。我們知道,在DOM節點構成的DOM樹中,子節點產生一個事件之後會逐級冒泡到父元素上:

事件委託就利用這一特性,只需給所有的按鈕的父元素比如container添加一個事件,這樣無論是哪個按鈕,只要觸發了綁定的事件都會冒泡到container上,我們只需判斷是不是你想監聽的按鈕即可。

var container = document.getElementById(container);container.addEventListener(click, function(e){    //擷取事件觸發對象    var target = e.target;    if(target.id == btn1){        alert(btn1);    }else if(target.id == btn2){        alert(btn2);    }});

這個方法還有一個明顯的好處是你不必再問以後建立的元素添加監聽。比如在上面的判斷裡添加

else if(target.id == btn3){    alert(btn3);}

添加這個事件處理常式的時候頁面中還並沒有btn3,但btn3很可能是由使用者動態建立的,但不管使用者什麼時候建立,你都能在這個條件裡捕獲它。

JQuery裡面的事件委託

其實在JQuery裡,因為很容易建立一個JQuery集合,所以處理事件相對簡單。

一、click函數、bind函數等:
$(a).click(function(){    if($(this).hasClass(a1)){        //...    }else if(...){        //...    }});$(a).bind(click, function(){    if($(this).hasClass(a1)){        //...    }else if(...){        //...    }});

其實這個方法同樣也是通過遍曆所有a標籤,給他們添加事件函數,但比原生js代碼量要少很多。

二、live()

live和上面講的原生js類似,不指定父元素的時候,將事件綁定在了document上,比如:

$(.link).live(click, function(){    //...});

當有事件冒泡到document上時,將檢查事件是否為click事件,元素是否帶有link的className,滿足這兩個條件則將觸發事件處理函數。
除了預設綁定在document上,也可以綁定在指定父元素上:

$(.link, $(#container)).live(click, function(){    //...});
三、delegate

其實不管是live還是bind,他們的寫法都很奇怪,我們討論的事件委託都是給父元素添加的事件監聽,但一直到現在都好像是在子項目上調用的方法,不過還好JQuery裡面還有一個函數:delegate。
同樣是綁定事件到.link篩選條件上,使用delegate方法如下:

$(#container).delegate(.link, click, function(){    //...});

可以看到,我們在需要綁定的父元素(id名為container的元素)上調用的delegate方法,並傳遞三個參數:監聽元素篩選條件、監聽事件名、事件處理函數。
通過鏈式調用更加舒服:

$(#container).delegate(.link, click, function(){    //...}).delegate(.btn, click, function(){    //...}).delegate(.whatever, click, function(){    //...});
注意

bind是不能為後面動態產生的元素繫結事件的(因為調用bind時遍曆的是當時頁面裡的所有元素)。
live和delegate是可以為動態產生的元素觸發事件處理函數的,因為綁定在父元素上的只是一個篩選條件。
最後需要注意的是同樣是綁定在document元素上的click事件:

$(.btn).live(click, function(){    //...});$(document).delegate(.btn, click, function(){    //...});

最好使用delegate方法,因為雖然live同樣是綁定在document上,但$(“.btn”)這句代碼還是會遍曆所有的.btn元素並給其建立JQuery對象,相比於直接使用document,效能上會有所不如。

當然,就拿寫法來說,我們也更應該喜歡delegate方法。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.