JavaScript:如何通过选择器获取父元素?

IT技术 javascript dom
2021-03-18 03:33:21

例子:

<div someAttr="parentDiv. We need to get it from child.">
    <table>
        ...
        <td> <div id="myDiv"></div> </td>
        ...
    </table>
</div>

我想通过一些选择器从内部 div 元素(带有myDiv类的元素)获取父级。

我如何在没有 jQuery 的情况下使用纯 JavaScript 实现这一点

就像是:

var div = document.getElementById('myDiv');
div.someParentFindMethod('some selector');
6个回答

您可以closest()在现代浏览器中使用

var div = document.querySelector('div#myDiv');
div.closest('div[someAtrr]');

使用对象检测来提供一种polyfill或替代方法,以实现与 IE 的向后兼容。

考虑到我们在 2018 年并且 Edge 支持这种方法,我认为这个答案应该是公认的。:-)
2021-04-23 03:33:21
只需包含这个polyfillgithub.com/jonathantneal/closest也可在 npm 上获得:npmjs.com/package/element-closest
2021-05-05 03:33:21
现在我们在 2021 年,所以这是完全可以接受的。这是目前最好的答案。
2021-05-13 03:33:21

这是最基本的版本:

function collectionHas(a, b) { //helper function (see below)
    for(var i = 0, len = a.length; i < len; i ++) {
        if(a[i] == b) return true;
    }
    return false;
}
function findParentBySelector(elm, selector) {
    var all = document.querySelectorAll(selector);
    var cur = elm.parentNode;
    while(cur && !collectionHas(all, cur)) { //keep going up until you find a match
        cur = cur.parentNode; //go up
    }
    return cur; //will return null if not found
}

var yourElm = document.getElementById("yourElm"); //div in your original code
var selector = ".yes";
var parent = findParentBySelector(yourElm, selector);
这是相当低效的,因为它检索整个文档中具有该选择器的所有元素,而不仅仅是检查父元素。
2021-04-19 03:33:21
同意用户663031
2021-05-07 03:33:21
JSPerf 测试为这些方法中的每一种分析Element.matches()Element.closest()和一个polyfillpolyfill forElement.matches()看起来与您的实现非常相似。为了解决@ user663031的性能问题,也许你可以使用Element.matches()代替Document.querySelectorAll()它似乎比相关的 polyfill 运行得更快。
2021-05-11 03:33:21

查找与给定选择器匹配的最近父元素(或元素本身)。还包括一个停止搜索的选择器,以防您知道应该停止搜索的共同祖先。

function closest(el, selector, stopSelector) {
  var retval = null;
  while (el) {
    if (el.matches(selector)) {
      retval = el;
      break
    } else if (stopSelector && el.matches(stopSelector)) {
      break
    }
    el = el.parentElement;
  }
  return retval;
}
最接近的是一个糟糕的名字,应该命名为“closestAncestor”,如果最近的祖先是10个元素,最近的后代是1个孩子,那么“最近的”将是后代,而不是祖先,但这个函数会返回祖先反而
2021-05-07 03:33:21

使用带有 indexOf 的 leech 答案(以支持 IE)

这是使用 leech 所说的,但使其适用于 IE(IE 不支持匹配):

function closest(el, selector, stopSelector) {
  var retval = null;
  while (el) {
    if (el.className.indexOf(selector) > -1) {
      retval = el;
      break
    } else if (stopSelector && el.className.indexOf(stopSelector) > -1) {
      break
    }
    el = el.parentElement;
  }
  return retval;
}

它并不完美,但如果选择器足够独特,它就可以工作,这样它就不会意外地匹配不正确的元素。

这是一个递归解决方案:

function closest(el, selector, stopSelector) {
  if(!el || !el.parentElement) return null
  else if(stopSelector && el.parentElement.matches(stopSelector)) return null
  else if(el.parentElement.matches(selector)) return el.parentElement
  else return closest(el.parentElement, selector, stopSelector)
}