事件委托是如何工作的

假如在一個 ul 中有著 100 個 li,當鼠標點擊一個 li 的時候,便執(zhí)行一些動作。完成以上功能必須給每個 li 都綁定一個事件嗎?顯然這么做有點浪費,畢竟要綁定 100 次,倘若能只綁定一次,就好了——說得便是事件委托

事件委托(Event Delegation)是 JavaScript 中十分常用的方法之一。事件委托允許你不監(jiān)聽那些具體(li)的元素,相應的把事件綁定在其父元素(ul)上。例如下面這段代碼:

<ul id="parent-list">
    <li class="child">Item 1</li>
    <li class="child">Item 2</li>
    <li class="child">Item 3</li>
    <li class="child">Item 4</li>
    <li class="child">Item 5</li>
    <li class="child">Item 6</li>
</ul>

如之前所說,分別給每個 li 的綁定事件,不僅看上去有些浪費,而且一旦再添加新的 li 的時候,還要再給新加入的元素綁定事件,沒法實現(xiàn)動態(tài)監(jiān)聽。但是父元素 ul 是不變的,給它綁定監(jiān)聽事件再合適不過。

關鍵問題是:怎么找到那個目標元素?請看下面代碼:

//找到父元素,給其綁定事件
document.getElementById("parent-list").addEventListener("click", function(e) {
  //找到真正的目標元素
  if(e.target && e.target.nodeName === "LI") {
      console.log(e.target.innerText);
  }
});

監(jiān)聽 ul,一旦子元素事件冒泡到父元素,通過 event.target 檢查是否找到了目標元素。如果沒找到,就忽略這次事件;找到了,則輸出目標元素內(nèi)容??梢渣c擊示例查看結(jié)果:

<a class="jsbin-embed" >JS Bin on jsbin.com</a><script src="http://static.jsbin.com/js/embed.min.js?3.41.10"></script>

這只是簡單的使用原生 JS 實現(xiàn)事件委托,其中還有許多不足——如果 li 內(nèi)還有子元素怎么辦?

<ul id="parent-list">
    <li class="child">
      <ul>
        <li>item 1</li>
        <li>item 2</li>
        <li>item 3</li>
        <li>item 4</li>
      </ul>
    </li>
    <li class="child">Item 2</li>
    <li class="child">Item 3</li>
    <li class="child">Item 4</li>
    <li class="child">Item 5</li>
    <li class="child">Item 6</li>
  </ul>

情況有兩點不同:

  1. 雖然點擊的元素時 li.child li,但實際的目標元素為 li.child
  2. 需要判斷點擊的元素是否在 li.child 之內(nèi)

對于第一點,使用 Element.matches() 或許會是個好主意[1]。第二點的解決辦法是:循環(huán)檢查點擊元素的父元素,止于監(jiān)聽元素。如下示例:

<a class="jsbin-embed" >JS Bin on jsbin.com</a><script src="http://static.jsbin.com/js/embed.min.js?3.41.10"></script>

當然,還有許多 DOM 庫在處理事件和元素時,有著更強大的功能,在實際應用中也很有幫助。

參考鏈接


  1. 較新的瀏覽器才支持 Element.matches(),可能會有兼容性的問題。 ?

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 總結(jié): 鼠標事件 1.click與dbclick事件$ele.click()$ele.click(handler(...
    阿r阿r閱讀 1,714評論 2 10
  • (續(xù)jQuery基礎(1)) 第5章 DOM節(jié)點的復制與替換 (1)DOM拷貝clone() 克隆節(jié)點是DOM的常...
    凜0_0閱讀 1,499評論 0 8
  • 1.背景介紹 1.1什么是事件委托? 事件委托還有一個名字叫事件代理,JavaScript高級程序設計上講:事件委...
    我叫于搞吧閱讀 1,713評論 4 9
  • 第1章 鼠標事件 1-1 jQuery鼠標事件之click與dbclick事件 用交互操作中,最簡單直接的操作就是...
    mo默22閱讀 1,343評論 0 6
  • 第三章 兒童的藝術發(fā)展 在幼兒階段,藝術發(fā)展必然與感知、身體、認知、語言、社會和情感發(fā)展密切相關。 藝術發(fā)展的基本...
    琥珀2017閱讀 813評論 0 1

友情鏈接更多精彩內(nèi)容