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

例如:

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

我想通过内部 div 元素(具有 myDiv类的元素)中的某个选择器来获取父元素。

如何使用普通的 JavaScript without jQuery实现这一点?

比如:

var div = document.getElementById('myDiv');
div.someParentFindMethod('some selector');
205552 次浏览

下面是最基本的版本:

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

Here is simple way to access parent 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>

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

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

Use object detection to supply a polyfill or alternative method for backwards compatability with IE.

Finds the closest parent (or the element itself) that matches the given selector. Also included is a selector to stop searching, in case you know a common ancestor that you should stop searching at.

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

一个函数 father _ by _ selector 的简单示例,它返回一个父函数或 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)

这是使用水蛭所说的,但使其工作的 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)
}

我认为我将提供一个更加健壮的例子,也是在类型脚本中,但是它很容易转换为纯 javascript。这个函数将使用类似“ # my-element”或类这样的 ID 来查询父类。与其中一些答案不同的是,这些答案可以处理多个类。我发现我命名了一些类似的东西,所以上面的例子找到了错误的东西。

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

按身份证选择:

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

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

通过使用 QuerySelector ()closest()方法可以得到父元素。

  • querySelector()返回与 specified CSS selector(s) in the document.

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

用法例子

const element = document.querySelector('td')


console.log(element.closest('div'))
<div>
<table>
<tr>
<td></td>
</tr>
</table>
</div>

在需要选择多个元素的情况下,querySelectorAll()是一个很好的选择。

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

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

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

const el = document.querySelectorAll('td')


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

这是一种使用递归获取具有特定类的父类的简单方法。您可以根据选择器对其进行修改以切换,但原理是相同的:

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


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


return parent;
}