97

例子:

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

11 回答 11

272

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

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

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

于 2016-02-17T09:29:00.457 回答
46

这是最基本的版本:

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);
于 2013-01-09T11:52:24.107 回答
43

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

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;
}
于 2016-07-01T16:06:52.057 回答
3

将 leech 的答案与 indexOf 一起使用(以支持 IE)

这是使用水蛭所说的,但使其适用于 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;
}

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

于 2017-01-24T21:27:18.713 回答
2

这是一个递归解决方案:

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)
}
于 2017-08-01T21:30:15.350 回答
2

我想我会提供一个更健壮的例子,也在打字稿中,但它很容易转换为纯 javascript。此函数将使用诸如“#my-element”之类的 ID 或类“.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;
}

按类名选择:

let elementByClassName = queryParentElement(someElement,".my-class")

按 ID 选择:

let elementByID = queryParentElement(someElement,"#my-element")

于 2019-09-02T19:02:07.973 回答
2

通过使用querySelector()最接近的()方法可以获得父元素。

  • querySelector()返回与文档中指定的 CSS 选择器匹配的第一个元素。

  • closest()在 DOM 树中搜索与指定 CSS 选择器匹配的最接近的元素。

使用示例

var element = document.querySelector('td');
console.log(element.closest('div'));
<div>
  <table>
    <tr>
      <td></td>
    </tr>
  </table>
</div>

如果需要选择多个元素,querySelectorAll()非常适合。

  • querySelectorAll()返回文档中与指定 CSS 选择器匹配的所有元素,作为静态 NodeList 对象。

要选择所需的元素,必须在内部指定它[],例如第二个元素是:element[1]

在以下示例closest()中,方法用于获取<tr>特定选定元素的父元素。

var element = document.querySelectorAll('td');
console.log(element[1].closest('tr'));
<div>
  <table>
    <tr id="1">
      <td> First text </td>
    </tr>
    <tr id="2">
      <td> Second text </td>
    </tr>
  </table>
</div>

于 2021-10-23T08:52:38.027 回答
0

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

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;
};
于 2016-12-18T06:34:44.067 回答
0

这是使用递归获取具有特定类的父级的简单方法。可以修改为根据选择器切换,但原理是一样的:

function findParentByClass(child, parentClass) {
    let parent = child.parentElement;

    while(!(parent.className === parentClass)){
        parent = findParentByClass(child.parentElement, parentClass)
    }

    return parent;
}
于 2022-02-27T02:51:49.673 回答
-4

这是访问父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>
于 2013-01-09T11:57:02.183 回答
-4
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 );
于 2020-07-08T09:57:40.240 回答