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

掘金翻譯計劃發表於2019-04-30

最近我在使用垂直導航元件的時候遇到了一個問題:點選選單項的時候,對應的 JavaScript 程式碼並沒有觸發。我對這個問題進行了比較深入的瞭解之後,分享下解決這個問題的過程以及在這過程中發現的技巧。

這個問題的場景是這樣的,所有的選單項都有兩個子元素:一個圖示,以及一個作為標籤的 <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 來控制二級選單的開啟/關閉狀態。

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 類。如果元素具有這個類,那麼二級選單將會被隱藏,否則會顯示二級選單:

var toggle = function (elem, timing) {

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

  // 否則,展示二級選單
  show(elem);
};
複製程式碼

我希望點選選單項中的任何位置,都會觸發 JavaScript 並且執行切換操作。但是如果我點選圖示或者標籤子元素,JavaScript 就不會執行。原因是 event.target 返回到的是實際點選到的 DOM 元素。點選圖示或者標籤只會返回圖示或者標籤元素。

closest() 方法

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

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 元素。closest() 方法在大多數主流瀏覽器上都是支援的,但是在 IE11 上需要引入 polyfill。

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

如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。


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

相關文章