[譯] 使用 closest() 函數獲取正確的 DOM 元素

最近我在使用垂直導航組件的時候遇到了一個問題:點擊菜單項的時候,對應的 JavaScript 代碼並無觸發。我對這個問題進行了比較深刻的瞭解以後,分享下解決這個問題的過程以及在這過程當中發現的技巧。html

這個問題的場景是這樣的,全部的菜單項都有兩個子元素:一個圖標,以及一個做爲標籤的 <span> 元素,這兩個元素均嵌入到了連接中。前端

<li>
  <a href="#example" class="toggle">
    <img src="/img/billing.svg" width="20" height="20" alt="">
    <span>Billing</span>
  </a>
  <div id="example">
    <ul>
      <li><a href="/statment/">My Statement</a></li>
      <li><a href="/history/">Pay History</a></li>
    </ul>
  </div>
</li>
複製代碼

<div> 元素中還有二級菜單,我添加了一些 JavaScript 來控制二級菜單的開啓/關閉狀態。android

document.addEventListener('click', function (event) {

  // 保證點擊的元素是能夠切換開關狀態的
  if (!event.target.classList.contains('toggle')) {
    return;
  }
  event.preventDefault();

  // 獲取元素內容
  var content = document.querySelector(event.target.hash);
  if (!content) {
    return;
  }

  // 切換內容的開啓/關閉狀態
  toggle(content);

}, false);
複製代碼

toggle 方法會觸發一個函數,這個函數會檢查二級菜單是否有 .is-visible CSS 類。若是元素具備這個類,那麼二級菜單將會被隱藏,不然會顯示二級菜單:ios

var toggle = function (elem, timing) {

  // 若是二級菜單是可見的,那麼就隱藏它
  if (elem.classList.contains('is-visible')) {
    hide(elem);
    return;
  }

  // 不然,展現二級菜單
  show(elem);
};
複製代碼

我但願點擊菜單項中的任何位置,都會觸發 JavaScript 而且執行切換操做。可是若是我點擊圖標或者標籤子元素,JavaScript 就不會執行。緣由是 event.target 返回到的是實際點擊到的 DOM 元素。點擊圖標或者標籤只會返回圖標或者標籤元素。git

closest() 方法

我須要獲取到觸發了點擊事件的目標,而且返回其父元素,而不是子元素。我採用了使用 closest() 方法的解決方案。這個方法會從當前元素開始,遍歷 DOM 樹,而且返回和給定參數匹配的最近的祖先:github

let closestElement = Element.closest(selector); 
複製代碼

這段代碼讓我醍醐灌頂。我能夠經過 closest()event.target 來找到而且返回父元素(菜單項連接),不管我點擊的是哪一個子元素(圖標或者標籤):後端

if (!event.target.closest('a').classList.contains('toggle')) {
  return;
}

var content = document.querySelector(event.target.closest('a').hash);
複製代碼

如今,點擊菜單項的任何地方都會觸發 JavaScript 而且切換二級菜單了。瀏覽器

能夠在 CODEPEN 上嘗試一下,而且還有源碼。dom

但願這個小竅門能夠幫助你定位特定的 DOM 元素。closest() 方法在大多數主流瀏覽器上都是支持的,可是在 IE11 上須要引入 polyfill。ide

若是你須要更加深刻的瞭解本文相關的內容,我推薦 Zell Liew 的關於遍歷 DOM 元素的文章。他介紹了本文使用的這種方法以及其餘一些值得一試的技巧。

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索