JavaScript事件委託的技術原理
如今的JavaScript技術界裡最火熱的一項技術應該是‘事件委託(event delegation)’了。使用事件委託技術能讓你避免對特定的每個節點新增事件監聽器;相反,事件監聽器是被新增到它們的父元素上。事件監聽器會分析從子元素冒泡上來的事件,找到是哪個子元素的事件。基本概念非常簡單,但仍有很多人不理解事件委託的工作原理。這裡我將要解釋事件委託是如何工作的,並提供幾個純JavaScript的基本事件委託的例子。
假定我們有一個UL元素,它有幾個子元素:
<ul id="parent-list"> <li id="post-1">Item 1</li> <li id="post-2">Item 2</li> <li id="post-3">Item 3</li> <li id="post-4">Item 4</li> <li id="post-5">Item 5</li> <li id="post-6">Item 6</li> </ul>
我們還假設,當每個子元素被點選時,將會有各自不同的事件發生。你可以給每個獨立的li元素新增事件監聽器,但有時這些li元素可能會被刪除,可能會有新增,監聽它們的新增或刪除事件將會是一場噩夢,尤其是當你的監聽事件的程式碼放在應用的另一個地方時。但是,如果你將監聽器安放到它們的父元素上呢?你如何能知道是那個子元素被點選了?
簡單:當子元素的事件冒泡到父ul元素時,你可以檢查事件物件的target屬性,捕獲真正被點選的節點元素的引用。下面是一段很簡單的JavaScript程式碼,演示了事件委託的過程:
// 找到父元素,新增監聽器... document.getElementById("parent-list").addEventListener("click",function(e) { // e.target是被點選的元素! // 如果被點選的是li元素 if(e.target && e.target.nodeName == "LI") { // 找到目標,輸出ID! console.log("List item ",e.target.id.replace("post-")," was clicked!"); } });
第一步是給父元素新增事件監聽器。當有事件觸發監聽器時,檢查事件的來源,排除非li子元素事件。如果是一個li元素,我們就找到了目標!如果不是一個li元素,事件將被忽略。這個例子非常簡單,UL和li是標準的父子搭配。讓我們試驗一些差異比較大的元素搭配。假設我們有一個父元素div,裡面有很多子元素,但我們關心的是裡面的一個帶有”classA” CSS類的A標記:
// 獲得父元素DIV, 新增監聽器... document.getElementById("myDiv").addEventListener("click",function(e) { // e.target是被點選的元素 if(e.target && e.target.nodeName == "A") { // 獲得CSS類名 var classes = e.target.className.split(" "); // 搜尋匹配! if(classes) { // For every CSS class the element has... for(var x = 0; x < classes.length; x++) { // If it has the CSS class we want... if(classes[x] == "classA") { // Bingo! console.log("Anchor element clicked!"); // Now do something here.... } } } } });
上面這個例子中不僅比較了標籤名,而且比較了CSS類名。雖然稍微複雜了一點,但還是很具代表性的。比如,如果某個A標記裡有一個span標記,則這個span將會成為target元素。這個時候,我們需要上溯DOM樹結構,找到裡面是否有一個 A.classA 的元素。
因為大部分程式設計師都會使用jQuery等工具庫來處理DOM元素和事件,我建議大家都使用裡面的事件委託方法,因為這裡工具庫裡都提供了高階的委託方法和元素甄別方法。
希望這篇文章能幫助你理解JavaScript事件委託的幕後原理,希望你也感受到了事件委託的強大用處!
英文:davidwalsh
相關文章
- JavaScript 事件委託詳解 | 掘金技術徵文JavaScript事件
- Js 事件原理與事件委託JS事件
- javascript中的事件委託(代理)JavaScript事件
- JavaScript 事件委託詳解JavaScript事件
- JavaScript 事件委託或者事件代理介紹JavaScript事件
- JavaScript 中的閉包和事件委託JavaScript事件
- 事件委託事件
- javascript事件委託程式碼例項JavaScript事件
- JavaScript進階系列06,事件委託JavaScript事件
- 委託、事件--委託例項篇事件
- js事件委託原理簡單介紹JS事件
- 委託與事件-委託詳解(一)事件
- jQuery 事件委託jQuery事件
- 事件模型和事件委託事件模型
- js中的事件委託JS事件
- C# 事件委託C#事件
- C#事件委託事件
- 重中之重:委託與事件事件
- C# 委託事件C#事件
- wpf移除事件委託事件
- JS事件流和事件委託JS事件
- 委託、Lambda表示式、事件系列01,委託是什麼,委託的基本用法,委託的Method和Target屬性事件
- 事件的捕獲、冒泡、委託事件
- jquery-中的事件委託jQuery事件
- Zepto事件委託的小坑事件
- js 事件的冒泡和委託JS事件
- 委託、Lambda表示式、事件系列07,使用EventHandler委託事件
- javascript什麼是事件委託簡單介紹JavaScript事件
- 委託、Lambda表示式、事件系列04,委託鏈是怎樣形成的, 多播委託, 呼叫委託鏈方法,委託鏈異常處理事件
- JQuery7:事件委託jQuery事件
- C#委託與事件C#事件
- C# 事件 vs 委託C#事件
- C# - 委託與事件C#事件
- c# 委託和事件C#事件
- 委託與事件-事件詳解(二)事件
- C# 委託原理刨析,外加和事件對比C#事件
- 事件委託---動態建立的元素新增事件事件
- Javascript事件模型系列(二)事件的捕獲-冒泡機制及事件委託機制JavaScript事件模型