如今的JavaScript技術界裡最火熱的一項技術應該是『事件委託(event delegation)'了。使用事件委託技術能讓你避免對特定的每個節點增加事件監聽器;相反,事件監聽器是被加入到它們的父元素上。事件監聽器會分析從子元素冒泡上來的事件,找出是哪個子元素的事件。基本概念非常簡單,但仍有許多人不理解事件委託的工作原理。這裡我將要解釋事件委託是如何運作的,並提供幾個純JavaScript的基本事件委託的例子。
假設我們有一個UL元素,它有幾個子元素:
複製程式碼
程式碼如下:
- Item 1
- Item 2
- Item 3
- Item 4
- Item 5
Item 6 複製程式碼
程式碼如下:
程式碼如下:
// 找到父元素,加入監聽器...
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").addEventListenerenerener ("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 // 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事件委託的幕後原理,希望你也感受到了事件委託的強大用處!