前端事件系統(二)

發表於2015-09-25

本章將把重點放在於對於事件的委託機制,以及jquery的事件繫結方法做一些解析。本章並沒有什麼比較難懂的地方,也還沒有深入到jQuery的事件系統內部。


事件委託

上一章講了前端事件系統以及簡單地對各個瀏覽器進行相容的方法。對於要求不高的頁面來說,之前的簡單事件註冊,就可以很好的勝任各種各樣的工作了。但是,試想一種情況。倘若一個頁面有著極大量的事件繫結的需求,那麼我們之前的事件系統,就不得不一個個的去繫結事件。這樣對效能來說,肯定是一種災難,同時,動態增加的節點無法完成繫結的工作。因此,我們需要引入事件委託這一機制。

冒泡與捕獲

我們知道dom的事件處理,分為捕獲階段,目標階段,以及冒泡階段三個部分。那麼簡單地講一下這三個階段吧,當我們點選了一個a標籤的時候,整個事件的流程大致是下面的階段

首先事件從dom樹向下傳送,逐個訪問目標節點的祖先節點,同時將會對該事件的捕獲事件監聽器來進行檢測,並執行,直到訪問到目標節點,這一階段就是我們說的捕獲階段;到達目標節點(即a標籤)後,就會執行該事件監聽器,這一階段也就是目標節點;最後事件將會從目標節點開始,從dom樹往上傳送,再依次訪問目標節點的祖先節點,並且執行對應的非捕獲事件的事件監聽器,並且執行

委託的原理

既然有了冒泡和捕獲的概念,那麼事件委託的原理也很好理解了。事件委託利用了事件可以傳播的這一特性,並不使用事件本身對於事件來進行處理,而是將對事件的處理任務交予了其祖先節點來進行處理。

這樣做,減少了對於頁面上的dom操作。比如你對ul下的li繫結事件,通過事件委託,你只需要對於ul繫結一次事件,然後使用事件傳播的這一特性,li的事件來進行工作,這樣,極大地減少了繫結量,而且即使是動態增加的li節點,也同樣是可以去執行該事件的。


jQuery的事件繫結

那麼終於來到了jQuery的部分。從這裡開始也將對jQuery的事件部分,盡個人所能來做一個解析,之後出現jQuery的原始碼的版本為2.1.4,解析過程中有不對的地方,歡迎打臉。

jQuery的事件繫結,有以下幾種方法:

  • 直接用click,blur等事件名的方法
  • bind方法
  • delegate
  • live方法
  • one方法
  • on方法

那麼我們對上面幾種方法來一一分析(本章暫不會對作為核心的on的原始碼來進行分析)

1.直接用事件名進行事件繫結即是直接採用類似.click(),.blur()的方式進行繫結那麼jQuery中是如何做到的呢

jQuery的實現很簡單,將事件直接通過each方法加入jQuery.fn上,然後在內部根據引數的不同直接對於jQuery的on或者trigger方法進行呼叫。

2.bind方法bind方法用於為一個元素繫結一個事件處理程式先來看看jQuery中的實現吧

3. live方法live方法拿到前面來說。這是jQuery現在已經不支援的方法。對於1.4.3以上的版本,推薦採delgate方法來,而對於1.7以上的版本,則推薦採用on方法來進行替代。具體採用live方法有什麼弊端,jQuery的文件之中已經闡述的非常明白了,至於為什麼會出現這個問題,本著刻苦求知的精神……我還並沒有去看,附上翻譯後的文件吧

源文件

4. delegate方法delegate方法也就是我們之前所提到的事件委託了。因為基於live之前的很多問題,jQuery在live之後的版本中增加了delgate方法(如今已經被on所取代)來看看現在的delegate是如何實現的吧

5. one方法

為元素新增事件。並且在元素上的事件只可以執行一次

具體實現

6. on方法

on方法在這裡不打算對原始碼進行閱讀,因為可以看到,上面的所有方法都是對於on方法的呼叫。因此jQuery的事件系統,核心就在於on方法了。因此jQuery的on方法將在後面進行分析,而這裡,只是對於on介面本身的一些說明。

on方法提供了繫結事件所有的功能。其API是這樣的

其實最後還有一個one引數,倘若傳入了1,那麼這個事件也就只執行一次,而實現的原理其實也就是使用off來解綁事件進行的操作了。

然後來看下別的引數分別是做些什麼的吧

因此再來對於前面五種方法來進行統一的分析。

直接用事件名進行事件繫結的方法與bind的方法,直接對於selector引數賦值為了null,因此,對於採用這兩種方法進行的事件繫結,其實本身是沒有使用事件委託的,即是說並沒有冒泡的過程,因此,採用這種方法的繫結對效能會有一定的損耗。而delegate方法,傳入了selector引數,因此,相當於也就是直接用on來實現的事件委託。one方法之前也講了,所以不再多說。


總結一下這章所講的內容吧。本章對於事件繫結的幾種方法(除on外),都進行了簡單地講解。與其說是對於jQuery原始碼的分析,倒不如說其實就是個簡單地,對於jQuery使用的建議吧。jQuery繫結的核心還是落在on方法上,同時,jQuery的事件系統的思想可以說是極為經典的。在下一章,我們將對jQuery的事件系統進行更深入一些的分析(在我捉急的水平範圍之內)。第三章估計要難產了,我一定會努力做完這個系列的,也算是對個人前端學習的一點鞭策吧。

相關文章