没有jQuery找到最接近的元素

hun*_*erc 83 javascript

我试图找到没有jquery的具有特定标签名称的最接近的元素.当我点击一个<th>我想要访问<tbody>该表时.建议?我读过有关偏移的内容,但并没有真正理解它.我应该使用:

假设th已经设置为单击了元素

th.offsetParent.getElementsByTagName('tbody')[0]
Run Code Online (Sandbox Code Playgroud)

ori*_*dam 104

非常简单:

el.closest('tbody')
Run Code Online (Sandbox Code Playgroud)

除IE以外的所有浏览器均支持
更新:Edge现在也支持它.

不需要jQuery.更过,更换jQuery的$(this).closest('tbody')使用$(this.closest('tbody'))将提高性能,显著时未找到该元素.

适用于IE的Polyfill:

if (!Element.prototype.matches) Element.prototype.matches = Element.prototype.msMatchesSelector;
if (!Element.prototype.closest) Element.prototype.closest = function (selector) {
    var el = this;
    while (el) {
        if (el.matches(selector)) {
            return el;
        }
        el = el.parentElement;
    }
};
Run Code Online (Sandbox Code Playgroud)

请注意,找不到return元素时没有,undefined当找不到最接近的元素时有效返回.

有关更多详细信息,请参阅:https: //developer.mozilla.org/en-US/docs/Web/API/Element/closest

  • 为什么这个答案在页面底部?应该在顶部.非常感谢 (3认同)
  • @史蒂夫莫瑞兹。现在最接近的是原生 JavaScript (2认同)

Ale*_*les 66

派对很少(很晚),但是.这应该做的伎俩:

function closest(el, selector) {
    var matchesFn;

    // find vendor prefix
    ['matches','webkitMatchesSelector','mozMatchesSelector','msMatchesSelector','oMatchesSelector'].some(function(fn) {
        if (typeof document.body[fn] == 'function') {
            matchesFn = fn;
            return true;
        }
        return false;
    })

    var parent;

    // traverse parents
    while (el) {
        parent = el.parentElement;
        if (parent && parent[matchesFn](selector)) {
            return parent;
        }
        el = parent;
    }

    return null;
}
Run Code Online (Sandbox Code Playgroud)

  • 很棒的答案,有效.MDN还有一个用于element.closest()的polyfill.Chrome在当前版本中包含element.matches(),因此不需要前缀.我刚刚将这个添加到我正在开发的应用程序中使用的库,Clibu. (2认同)
  • 我已经更改了代码,以便它也可以测试jQuery.closest()和Element.closest()的元素“ el”。`for(var parent = el; parent!== null &amp;&amp;!parent [matchesFn](selector); parent = el.parentElement){el = parent; }返回父级;` (2认同)

Joo*_*oon 20

以下是如何在没有jQuery的情况下按标签名称获取最接近的元素:

function getClosest(el, tag) {
  // this is necessary since nodeName is always in upper case
  tag = tag.toUpperCase();
  do {
    if (el.nodeName === tag) {
      // tag name is found! let's return it. :)
      return el;
    }
  } while (el = el.parentNode);

  // not found :(
  return null;
}

getClosest(th, 'tbody');
Run Code Online (Sandbox Code Playgroud)

  • 我不相信这会奏效。它只检查 DOM 树。th-&gt;thead-&gt;table 从不考虑兄弟姐妹 (2认同)
  • 你应该在你的问题中陈述具体案例. (2认同)
  • 看。此函数遍历 parentNodes 以找到使用所提供标签的最近父节点(甚至通过扩展)。这不会“向下”文档树,只会“向上”。普通用户最有可能将“最近的”节点视为最近的兄弟节点。他只是不知道他需要的术语。 (2认同)

Mat*_*vis 6

function closest(el, sel) {
    if (el != null)
        return el.matches(sel) ? el 
            : (el.querySelector(sel) 
                || closest(el.parentNode, sel));
}
Run Code Online (Sandbox Code Playgroud)

此解决方案使用HTML 5规范的一些最新功能,并在旧版/不兼容的浏览器(读取:Internet Explorer)上使用此功能将需要填充.

Element.prototype.matches = (Element.prototype.matches || Element.prototype.mozMatchesSelector 
    || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector 
    || Element.prototype.webkitMatchesSelector || Element.prototype.webkitMatchesSelector);
Run Code Online (Sandbox Code Playgroud)


dav*_*995 5

有一个标准化的函数可以执行此操作:Element.closest。除IE11之外,大多数浏览器都支持它(caniuse.com会提供详细信息)。该MDN文档还包括如果你有目标旧版浏览器的一个填充工具。

要查找tbody给定的最接近的父级th,可以执行以下操作:

th.closest('tbody');
Run Code Online (Sandbox Code Playgroud)

如果您想自己编写函数,这是我想到的:

function findClosestParent (startElement, fn) {
  var parent = startElement.parentElement;
  if (!parent) return undefined;
  return fn(parent) ? parent : findClosestParent(parent, fn);
}
Run Code Online (Sandbox Code Playgroud)

要通过标签名称查找最接近的父级,可以这样使用:

findClosestParent(x, element => return element.tagName === "SECTION");
Run Code Online (Sandbox Code Playgroud)