JavaScript 事件繫結

admin發表於2020-06-17

在文章開頭先提一下React的事件繫結,React 裡只需把事件處理器(event handler)以駱峰命名(camelCased)形式當作元件的 props 傳入即可,就像使用普通 HTML 那樣。React 內部建立一套合成事件系統來使所有事件在 IE8 和以上瀏覽器表現一致。也就是說,React 知道如何冒泡和捕獲事件,而且你的事件處理器接收到的 events 引數與 W3C 規範 一致,無論你使用哪種瀏覽器。

如果需要在手機或平板等觸控裝置上使用 React,需要呼叫 React.initializeTouchEvents(true); 啟用觸控事件處理。

在後續的一篇文章中,我將詳細說明一下關於React事件的繫結及最大化公用事件。


自動繫結和事件代理

實際上,React 做了一些操作來讓程式碼高效執行且易於理解。

(1).Autobinding: 在 JavaScript 裡建立回撥的時候,為了保證 this 的正確性,一般都需要顯式地繫結方法到它的例項上。有了 React,所有方法被自動繫結到了它的元件例項上。React 還快取這些繫結方法,所以 CPU 和記憶體都是非常高效。而且還能減少打字!

(2).事件代理 : React 實際並沒有把事件處理器繫結到節點本身。當 React 啟動的時候,它在最外層使用唯一一個事件監聽器處理所有事件。當元件被載入和解除安裝時,只是在內部對映裡新增或刪除事件處理器。當事件觸發,React 根據對映來決定如何分發。當對映裡處理器時,會當作空操作處理。參考 David Walsh 很棒的文章 瞭解這樣做高效的原因。

在JavaScript中,事件委託是一種很常用也很合理的方法。事件委託可以讓你避免新增事件監聽器監聽特定的節點,相反,事件委託是將事件緊監聽放在父級節點上。該事件監聽冒泡事件,找到子元素進行匹配。下面舉個例子來說明一下事件委託的工作原理:


首先,我們有一些子元素的你UL元素:

[HTML] 純文字檢視 複製程式碼
<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元素被頻繁的從列表中新增和刪除呢?新增和刪除事件偵聽器將是一場噩夢,尤其是如果新增和移除程式碼在Li的應用程式中不同的地方。更好的解決方案是一個事件監聽器新增到父UL元素。但是,如果你新增事件監聽到父UL,你將如何知道被點選哪些元素?

[JavaScript] 純文字檢視 複製程式碼
// Get the element, add a click listener...
document.getElementById("parent-list").addEventListener("click", function(e) {
    // e.target is the clicked element!
    // If it was a list item
    if(e.target && e.target.nodeName == "LI") {
        // List item found!  Output the ID!
        console.log("List item ", e.target.id.replace("post-", ""), " was clicked!");
    }
});

通過增加一個click事件偵聽父元素開始。當事件聽者被觸發,檢查事件元件,以確保它的元素反應以型別。如果它是一個LI元素,但是,如果這不是我們想要的元素,該事件可以被忽略。這個例子是非常簡單 - UL和LI是一個直接的比較。讓我們嘗試一些更加困難。讓我們多子元素的父級DIV ,但我們關心的是與ClassA的CSS類的標記

[JavaScript] 純文字檢視 複製程式碼
// Get the parent DIV, add click listener...
document.getElementById("myDiv").addEventListener("click",function(e) {
    // e.target was the clicked element
  if (e.target && e.target.matches("a.classA")) {
    console.log("Anchor element clicked!");
    }
});

使用Element.matches API ,我們可以看到,如果匹配元素我們所期望的目標。

相關文章