在優化網頁性能的技巧當中,對DOM的優化是必不可少的。這其中就涉及到了javascript對DOM的頻繁操做。好比響應用戶操做的事件。通常狀況下,若是是稍微初級一點的前端程序員,在拿到項目的時候,對待添加DOM事件,可能有些不會去考慮到這個性能的優化問題(好比我),這就會致使頁面中有大量的冗餘的DOM操做事件。無疑是增長了內存和開銷同時下降了網頁的性能。javascript
在對添加DOM事件,能夠嘗試着去優化一下代碼。這就是這裏要說到的事件委託機制。事件委託機制的含義在網上一搜不管是官方的解釋仍是廣大網友的分享。均可以大概從其中理解到一些:對於子元素須要添加的事件,把它委託給父元素。也就是說在父元素上綁定這個事件。當子元素觸發事件時,會冒泡到父元素上面,天然就會觸發這個綁定在父元素上面的事件了。前端
對於上述的事件委託,有兩個須要理解的問題:事件冒泡,獲取觸發事件的元素。java
1)事件冒泡:node
要說到事件冒泡的話,就要說說它的對手,事件捕獲。這二者都屬於事件流。也就是說事件流是分爲冒泡事件流和捕獲事件流。事件流的解釋就是--頁面接收事件的順序。程序員
冒泡就是自下而上。像冒泡泡同樣從子元素一直往上竄。而捕獲恰好相反:從頁面根節點(document)到裏層元素。這兩個事件使用頻率比較高的是事件冒泡。好比這裏要用到的事件委託,就是使用到了事件冒泡機制。性能
2)獲取觸發事件的元素優化
當父元素裏面的子元素觸發了事件,這個時候,就會發生事件的冒泡,一直到綁定事件的父元素上面就會觸發事件。事件冒泡的圖截取網上的以下:3d
冒泡到父元素以後,父元素如何得知此時是哪一個子元素觸發了事件呢?這會使用到一個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這些就不能夠冒泡。關於哪些事件不能冒泡須要網上查閱一下資料。在使用的時候注意一下就能夠了。