例項分析JavaScript中的事件委託和事件繫結
我們在學習JavaScript中,難免都會去網上查一些資料。也許偶爾就會遇到“事件委託”(也有的稱我“事件代理”,這裡不評論誰是誰非。以下全部稱為“事件委託”),尤其是在查JavaScript的事件處理的時候。但是,大多數時說的是“事件繫結”,對於“事件委託”,或是不提,或是淺嘗輒止。對於我這個比較好奇的人來說,實在很蛋疼。尤其是想更多的瞭解“事件委託”的時候。
這次乾脆一勞永逸,自己把查出來的資料整理成一篇日誌,總結這塊的知識,也方便需要的朋友查閱。
JavaScript中事件傳播過程那些事兒
早期的web開發,瀏覽器廠商很難回答一個哲學上的問題:當你在頁面上的一個區域點選時,你真正感興趣的是哪個元素。這個問題帶來了互動的定義。在一個元素的界限內點選,顯得有點含糊。畢竟,在一個元素上的點選同時也發生在另一個元素的界限內。例如單擊一個按鈕。你實際上點選了按鈕區域、body元素的區域以及html元素的區域。
伴隨著這個問題,兩種主流的瀏覽器Netscape和IE有不同的解決方案。Netscape定義了一種叫做事件捕獲的處理方法,事件首先發生在DOM樹的最高層物件(document)然後往最深層的元素傳播。在圖例中,事件捕獲首先發生在document上,然後是html元素,body元素,最後是button元素。
IE的處理方法正好相反。他們定義了一種叫事件冒泡的方法。事件冒泡認為事件促發的最深層元素首先接收事件。然後是它的父元素,依次向上,知道document物件最終接收到事件。儘管相對於html元素來說,document沒有獨立的視覺表現,他仍然是html元素的父元素並且事件能冒泡到document元素。所以圖例中噢噢那個button元素先接收事件,然後是body、html最後是document。如下圖:
圖1-JavaScript時間冒泡和捕捉
事件冒泡:
什麼是“事件冒泡”呢?假設這裡有一杯水,水被用某種神奇的方式分成不同顏色的幾層。這時,從最底層冒出了一個氣泡,氣泡會一層一層地上升,直到最頂層。而你不管在水的哪一層觀察都可以看到並捕捉到這個氣泡。好了,把“水”改成“DOM”,把“氣泡”改成“事件”。這就是“事件冒泡”。
氣泡帶上了某種資訊,會告訴其經過的每一層自己是在哪一層產生的。JavaScript的事件確實會帶著這個屬性。當程式捕獲一個事件的時候,它會知道這個事件來自於頁面上哪個元素。 事件委託也就是利用這個原理。
事件委託和事件繫結的簡介
事件繫結的介紹,網上比比皆是,大家也比較熟悉,D瓜哥文筆不好,就不獻醜了。
下面我們來重點介紹一下“事件委託”。其實,“事件委託”的概念很簡單,生活中也不乏這樣的例子。比如,有三個同事預計會在週一收到快遞。為簽收快遞,有兩種辦法:一是三個人在公司門口等快遞;二是委託給前臺MM代為簽收。現實當中,我們大都採用委託的方案(公司也不會容忍那麼多員工站在門口就為了等快遞)。前臺MM收到快遞後,她會判斷收件人是誰,然後按照收件人的要求籤收,甚至代為付款。這種方案還有一個優勢,那就是即使公司裡來了新員工(不管多少),前臺MM也會在收到寄給新員工的快遞後核實並代為簽收。
事件委託和事件繫結的程式碼實現
事件繫結的程式碼,網上一抓一把。這裡只給出一個簡單程式碼。諸如:
1 |
2 |
3 |
D瓜哥在第一次注意到事件委託的時候,明白這個大概意思。不過,陸游他老人家有句話說的好,“紙上得來終覺淺,絕知此事要躬行。”英語有一個很“心領神會”的一句話,是世界著名計算機專家Donald Knuth說的,”An algorithm must be seen to be believe!“D瓜哥從第一次注意到“事件委託”後,就考慮用程式碼如何實現。相信,這也是很多人第一次注意到“事件委託”的想法吧。哈哈
這裡給大家一個簡要的示例。示例如下:
01 |
02 |
03 |
04 |
05 |
06 |
07 |
08 |
09 |