资讯专栏INFORMATION COLUMN

使用 closest() 函数获取正确的 DOM 元素

leo108 / 709人阅读

摘要:保证点击的元素是可以切换开关状态的获取元素内容切换内容的开启关闭状态方法会触发一个函数,这个函数会检查二级菜单是否有类。


原文地址:Using closest() to return the correct DOM element

原文作者:Matt Smith

译文出自:掘金翻译计划

本文永久链接:github.com/xitu/gold-m…

译者:LucaslEliane

校对者:ZYuMing,Moonliujk

使用 closest() 函数获取正确的 DOM 元素

最近我在使用垂直导航组件的时候遇到了一个问题:点击菜单项的时候,对应的 JavaScript 代码并没有触发。我对这个问题进行了比较深入的了解之后,分享下解决这个问题的过程以及在这过程中发现的技巧。

这个问题的场景是这样的,所有的菜单项都有两个子元素:一个图标,以及一个作为标签的 元素,这两个元素均嵌入到了链接中。

<li>
  <a href="#example" class="toggle">
    <img src="/img/billing.svg" width="20" height="20" alt="">
    <span>Billingspan>
  a>
  <div id="example">
    <ul>
      <li><a href="/statment/">My Statementa>li>
      <li><a href="/history/">Pay Historya>li>
    ul>
  div>
li>

元素中还有二级菜单,我添加了一些 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 链接。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/6828.html

相关文章

  • 原生js替换jQuery各种方法-中文版

    摘要:本项目总结了大部分替代的方法,暂时只支持以上浏览器。返回指定元素及其后代的文本内容。从服务器读取数据并替换匹配元素的内容。用它自己的方式处理,原生遵循标准实现了最小来处理。当全部被解决时返回,当任一被拒绝时拒绝。是创建的一种方式。 原文https://github.com/nefe/You-D... You Dont Need jQuery showImg(https://segmen...

    lylwyy2016 评论0 收藏0
  • jQuery基础(二)DOM

    摘要:将匹配元素集合的父级元素删除,保留自身和兄弟元素,如果存在在原来的位置。方法查找指定元素集合中每一个元素的同辈元素。每次回调函数执行时,会传递当前循环次数作为参数从开始计数。 DOM节点的创建 先介绍下需要用到的浏览器提供的一些原生的方法(这里不处理低版本的IE兼容问题)创建流程比较简单,大体如下: 创建节点(常见的:元素、属性和文本) 添加节点的一些属性 加入到文档中流程中涉及的一...

    Harpsichord1207 评论0 收藏0
  • jQuery DOM节点遍历

    摘要:只要符合,不管是儿子辈,孙子辈都可以与其他的树遍历方法不同,选择器表达式对于是必需的参数。方法以选定的元素为中心,往内查找可以通过方法。要一个一个给合集中每一个设置颜色,这里方法就是方法就是一个循环的迭代器,它会迭代对象合集中的每一个元素。 children()方法 jQuery是一个合集对象,如果想快速查找合集里面的第一级子元素,此时可以用children()方法。这里需要注意:.c...

    Elle 评论0 收藏0
  • closest() 方法获得匹配选择器第一个祖先元素

    摘要:当被最接近的列表元素或其子后代元素被点击时,会切换黄色背景定义和用法方法获得匹配选择器的第一个祖先元素,从当前元素开始沿树向上。详细说明如果给定表示元素集合的对象,方法允许我们检索树中的这些元素以及它们的祖先元素,并用匹配元素构造新的对象。 w3c: http://www.w3school.com.cn/jquery/traversing_closest.asp 本例演示如何通过 c...

    seanlook 评论0 收藏0
  • JSLite 与jQuery有着类似api,模仿jQuery语法规范,并不是100%覆盖【官方

    摘要:与有着绝大部分类似的,通用库只有,手机上每一都是钱。目前及的最新版已经支持。在这个函数中,原来的对象是无效的。与方法相同,接受一个标准格式的字符串,并返回解析后的对象。这有点像,但是是相反的方式。 [JSLite.io] showImg(https://img.shields.io/github/issues/JSLite/JSLite.svg); showImg(https://im...

    Kyxy 评论0 收藏0

发表评论

0条评论

leo108

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<