淺談Javascript事件委託(代理)

首先祝你們七夕快樂。。
假如如今有一個的列表,裏面可能會有若干個列表項。如今要爲每個列表項綁定相同的點擊事件,如今你可能會有這幾種作法:node

  1. 手動爲每個列表項綁定事件;瀏覽器

  2. 在onload的時候,找到該列表,對其每個子元素進行遍歷,循環綁定事件;函數

  3. 給每個列表項相同的類名,一次性對其進行綁定。性能

方法1: 對於5個之內的列表項還好,若是列表有不少,好比100+,那麼這種方法很不現實,代碼會很是多,並且難以維護。
方法2: 代碼量看上去應該很少,可是一樣會難以維護,若是是動態生成的列表項,頗有可能會出現問題。最重要的,若是有大量列表項,性能會變得十分糟糕。
方法3: 原生JS不能直接選擇class就不說了,即便經過匹配className的方法進行綁定,其性能只會比方法2還要差。code

綜上所述,JS完了(誤)。對象


開玩笑啦,js提供一種方法叫作**事件委託**。事件

在講事件委託以前,咱們不妨先了解一下事件的三個階段(對事件冒泡有所瞭解的可跳過此段):文檔

捕獲階段——衆裏尋他千百度:
事件從文檔根節點出發,隨着DOM結構向事件的目標節點尋找。途中通過各個層次的DOM node,並在各node上觸發捕獲事件,直到到達時間的目標node。get

目標階段——終於等到你,還好我沒放棄:
事件到達目標node,在目標node上被觸發。io

冒泡階段——山谷迴音:
事件在目標node上觸發後,將由DOM樹一層層向上冒泡,依次觸發,直到到達最外層的根節點。這是時間委託所利用的特色。

請原諒我用這麼文藝的方式給你們講述事件觸發的故事。O(∩_∩)O

懂得了事件冒泡的過程,就很容易明白事件委託的運做原理。當列表項的事件冒泡到父元素(即列表元素)時,能夠查看事件對象的target屬性,catch真正被點擊的節點元素。下面是一段簡單代碼展現了這個過程:

document.getElementById("list").addEventListener("click",function(e) {
        if(e.target && e.target.nodeName == "LI") {
            //TO DO SOMETHING
        }
    });

解釋一下代碼: 得到父級元素list,爲其綁定點擊事件:若是子元素(列表項)被點擊,當事件冒泡到list時,判斷目標節點(事件來源)是否爲li元素,若是是則觸發該事件。
平常的例子: 假如你是一位小學班主任,你制定了一個規則:若是班裏有人早戀就必須受到懲罰(定義了事件觸發後執行的函數)。可是學生的活動範圍是整個學校而不是侷限於一個班,因此你就每天在學校裏溜達(將事件綁定到父級元素)。忽然看到有學生在接吻(事件句柄),你須要判斷這個學生是否是本身班裏的,若是是,請暴揍他一頓(觸發事件,他仍是個孩子,請不要放過他)。

固然,在真正的實際應用中也許沒有這麼簡單,你也許只須要其中部分子元素綁定事件;也許還要考慮瀏覽器兼容的問題(在IE裏目標元素放在srcElement屬性中而不是target中,因此最好把得到目標元素寫成一個跨瀏覽器的函數)。不過不管如何,你不須要爲不肯定的DOM而常常改變你的綁定,更不會由於過多的綁定致使性能的下降,大大下降崩潰的風險。

相關文章
相關標籤/搜索