1. 程式人生 > >js 事件委托代理

js 事件委托代理

問題 如果 nodename images gray 增加 ima 資料 alt

在優化網頁性能的技巧當中,對DOM的優化是必不可少的。這其中就涉及到了javascript對DOM的頻繁操作。比如響應用戶操作的事件。一般情況下,如果是稍微初級一點的前端程序員,在拿到項目的時候,對待添加DOM事件,可能有些不會去考慮到這個性能的優化問題(比如我),這就會導致頁面中有大量的冗余的DOM操作事件。無疑是增加了內存和開銷同時降低了網頁的性能。

在對添加DOM事件,可以嘗試著去優化一下代碼。這就是這裏要說到的事件委托機制。事件委托機制的含義在網上一搜無論是官方的解釋還是廣大網友的分享。都可以大概從其中理解到一些:對於子元素需要添加的事件,把它委托給父元素。也就是說在父元素上綁定這個事件。當子元素觸發事件時,會冒泡到父元素上面,自然就會觸發這個綁定在父元素上面的事件了。

對於上述的事件委托,有兩個需要理解的問題:事件冒泡,獲取觸發事件的元素。

1)事件冒泡:

要說到事件冒泡的話,就要說說它的對手,事件捕獲。這兩者都屬於事件流。也就是說事件流是分為冒泡事件流和捕獲事件流。事件流的解釋就是--頁面接收事件的順序。

冒泡就是自下而上。像冒泡泡一樣從子元素一直往上竄。而捕獲剛好相反:從頁面根節點(document)到裏層元素。這兩個事件使用頻率比較高的是事件冒泡。比如這裏要用到的事件委托,就是使用到了事件冒泡機制。

2)獲取觸發事件的元素

當父元素裏面的子元素觸發了事件,這個時候,就會發生事件的冒泡,一直到綁定事件的父元素上面就會觸發事件。事件冒泡的圖截取網上的如下:

技術分享圖片

冒泡到父元素之後,父元素如何得知此時是哪個子元素觸發了事件呢?這會使用到一個event對象。event的獲取和它的一些比較詳細的介紹可自行網上搜索。而這裏需要使用到的是event的一些屬性

(1) event.target /event.srcElement

獲取事件源(源頭),也就是事件到底是由誰觸發的,而不是說事件綁定在誰身上誰才能觸發。比如這裏說的事件綁定在父元素上,但是子元素可以觸發這個事件。

(2)event.target.nodeName

target下面的nodeName或者什麽id,className之類的都是要獲取具體的子元素。因為target它得到的是形如這樣的:

<li class="myLi">第一項</li>

有了上面這些之後,就可以著手去寫事件代理了:

技術分享圖片

給父元素ul綁定事件

技術分享圖片

如上所示,當點擊某一個li的時候,li的background變為lightgray,其他的保持white顏色。這就是事件的代理。只給父元素添加事件。而子元素通過冒泡的形式冒到父元素的時候就會觸發這個綁定的事件。這就明顯的減少了對DOM 的操作。從而優化了網頁的性能。

上面有一個註釋掉的一段代碼。它的這個意思是:事件綁定到父元素的上面,那麽子元素點擊一定會觸發父元素的事件。但是這個時候我不想要子元素觸發父元素的事件。此時拋掉這個事件代理。因為這個跟事件代理沒什麽關系了。所以我要阻止子元素觸發父元素事件的話。有個方法是在每個子元素上添加事件,並且阻止冒泡的傳遞。這樣感覺又得不償失了。所以使用e.target判斷當前點擊的是子元素的話就不要觸發這個事件。也就只有點擊的是自己的時候才觸發這個事件。

回到事件代理。如果子元素的事件都不一樣,那麽代碼就需要進行相應的修改了。可以使用到這個e.target上的一系列比如id,className之類的來判斷當前點擊的是哪個子元素,然後使用if/else,或者switch也好。分別進行處理。

當然事件冒泡也不是所有的事件都帶有的。有的事件就沒有。當然我們常用的click,鍵盤事件,mousedown這樣的。是可以冒泡的。但是focus/blur這些就不可以冒泡。關於哪些事件不能冒泡需要網上查閱一下資料。在使用的時候註意一下就可以了。

js 事件委托代理