委託活動
讓我們從示例開始。這是一個非常簡單的 HTML 示例。
示例 HTML
<html>
<head>
</head>
<body>
<ul>
<li>
<a href="some_url/">Link 1</a>
</li>
<li>
<a href="some_url/">Link 2</a>
</li>
<li>
<a href="some_url/">Link 3</a>
</li>
</ul>
</body>
</html>
問題
現在在這個例子中,我們想要為所有 <a>
元素新增一個事件監聽器。問題是此示例中的列表是動態的。隨著時間的推移,新增和刪除 <li>
元素。但是,頁面不會在更改之間重新整理,這將允許我們使用簡單的單擊事件偵聽器來連結物件(即 $('a').click()
)。
我們遇到的問題是如何將事件新增到來去的 <a>
元素中。
背景資訊 - 事件傳播
委託事件只能由於事件傳播(通常稱為事件冒泡)而發生。每當一個事件被觸發時,它將一直冒泡(到文件根目錄)。它們將事件的處理委託給不變的祖先元素,因此命名為委託事件。
因此,在上面的示例中,單擊 <a>
元素連結將按以下順序觸發這些元素中的 click
事件:
- 一個
- 裡
- UL
- 身體
- HTML
- 檔案根
解
知道什麼事件冒泡,我們可以捕獲一個通過我們的 HTML 傳播的通緝事件。
在這個例子中捕獲它的一個好地方是 <ul>
元素,因為該元素不是動態的:
$('ul').on('click', 'a', function () {
console.log(this.href); // jQuery binds the event function to the targeted DOM element
// this way `this` refers to the anchor and not to the list
// Whatever you want to do when link is clicked
});
在上面:
- 我們有’ul’這個事件監聽器的接收者
- 第一個引數(‘click’)定義了我們要檢測的事件。
- 第二個引數(‘a’)用於宣告事件需要源自的位置(此事件偵聽器的收件人下的所有子元素,ul)。
- 最後,第三個引數是在滿足第一個和第二個引數要求時執行的程式碼。
詳細解決方案如何工作
- 使用者點選
<a>
元素 - 這會觸發
<a>
元素上的 click 事件。 - 事件開始冒泡到文件根目錄。
- 事件首先到
<li>
元素,然後到<ul>
元素。 - 事件監聽器在
<ul>
元素附加事件監聽器時執行。 - 事件偵聽器首先檢測觸發事件。冒泡事件是點選,聽眾有點選,這是一個傳球。
- 監聽器檢查嘗試將第二個引數(‘a’)與氣泡鏈中的每個項匹配。由於鏈中的最後一項是’a’,這與過濾器匹配,這也是一個過程。
- 第三個引數中的程式碼使用匹配的專案執行,因為它是
this
。如果該函式不包含對stopPropagation()
的呼叫,則該事件將繼續向上傳播到根(document
)。
注意:如果沒有合適的不變的祖先/方便,你應該使用 document
。作為習慣,不要使用'body'
,原因如下:
body
有一個 bug,與樣式有關,這可能意味著滑鼠事件不會冒泡。這取決於瀏覽器,並且可以在計算的身高為 0 時發生(例如,當所有子元素具有絕對位置時)。滑鼠事件總是起泡到document
。document
始終存在於你的指令碼中,因此你可以將委派的處理程式附加到支援 DOM 的處理程式之外的document
,並確保它們仍然可以工作。