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

JavaScript:如何通过选择器获取父元素?,javascript,dom,Javascript,Dom,例如: ... ... 我想通过一些选择器从内部div元素中获取父元素,即带有myDiv类的元素 我如何在没有jQuery的情况下使用纯JavaScript实现这一点 比如: var div=document.getElementById'myDiv'; div.someparentfind方法“一些选择器”; 以下是最基本的版本: function collectionHas(a, b) { //helper function (see below) for(var i = 0, le

例如:

... ... 我想通过一些选择器从内部div元素中获取父元素,即带有myDiv类的元素

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

比如:

var div=document.getElementById'myDiv'; div.someparentfind方法“一些选择器”;
以下是最基本的版本:

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);

下面是访问父id的简单方法

document.getElementById("child1").parentNode;
将为您访问父div发挥神奇的作用

<html>
<head>
</head>
<body id="body">
<script>
function alertAncestorsUntilID() {
var a = document.getElementById("child").parentNode;
alert(a.id);
}
</script>
<div id="master">
Master
<div id="child">Child</div>
</div>
<script>
alertAncestorsUntilID();
</script>
</body>
</html>
您可以在现代浏览器中使用:

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

使用对象检测提供向后兼容IE的方法或替代方法。

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

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;
}

函数parent_by_选择器返回parent或null的简单示例没有选择器匹配:

function parent_by_selector(node, selector, stop_selector = 'body') {
  var parent = node.parentNode;
  while (true) {
    if (parent.matches(stop_selector)) break;
    if (parent.matches(selector)) break;
    parent = parent.parentNode; // get upper parent and check again
  }
  if (parent.matches(stop_selector)) parent = null; // when parent is a tag 'body' -> parent not found
  return parent;
};
使用带有indexOf的leech答案支持IE 这是使用leech所说的,但使其适用于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)
}

我想我会提供一个更加健壮的示例,同样是在typescript中,但它很容易转换为纯javascript。此函数将使用ID like so my元素或类来查询父级。my class和不像这些答案中的一些将处理多个类。我发现我给一些人起了类似的名字,所以上面的例子发现了错误的东西

function queryParentElement(el:HTMLElement | null, selector:string) {
    let isIDSelector = selector.indexOf("#") === 0
    if (selector.indexOf('.') === 0 || selector.indexOf('#') === 0) {
        selector = selector.slice(1)
    }
    while (el) {
        if (isIDSelector) {
            if (el.id === selector) {
                return el
            }
        }
        else if (el.classList.contains(selector)) {
            return el;
        }
        el = el.parentElement;
    }
    return null;
}
要按类名选择: 让elementByClassName=QueryParentElement.my类

要按ID选择,请执行以下操作:
让elementByID=QueryParentElement,my element

Google只提供jQuery.parent everywhere。请根据下面@soullivaneuh的建议更新所选答案。jQuery最适合不使用jQuery的人-这是相当低效的,因为它使用该选择器检索整个文档中的所有元素,而不仅仅是检查父级。这将为这些方法中的每种方法分析Element.matches、Element.closest和一个polyfill。Element.matches的polyfill看起来与您的实现非常相似。为了解决@user663031的性能问题,也许可以使用Element.matches而不是Document.querySelectorAll。它的运行速度似乎比相关的polyfill快。同意用户663031,他希望父元素具有某种类,而不仅仅是父元素。@torazaburo这是OP JavaScript提出的问题:如何通过选择器获取父元素?它没有提到ClassSelector也可以是一个类或属性,因此考虑到我们在2018年,Edge支持这种方法,我认为这个答案应该是可以接受的:-只需包含此多边形填充:。也可在npm上获得:。现在我们是在2021年,所以这是可以接受的。这是现在最好的答案。我欠你一杯啤酒!谢谢!
var base_element = document.getElementById('__EXAMPLE_ELEMENT__');
for( var found_parent=base_element, i=100; found_parent.parentNode && !(found_parent=found_parent.parentNode).classList.contains('__CLASS_NAME__') && i>0; i-- );
console.log( found_parent );