如何在纯JavaScript中找到最接近具有特定类的树的元素的祖先?例如,在这样的树中:
<div class="far ancestor">
<div class="near ancestor">
<p>Where am I?</p>
</div>
</div>
然后是div。near。祖宗如果我在p上尝试这个,然后搜索祖宗。
如何在纯JavaScript中找到最接近具有特定类的树的元素的祖先?例如,在这样的树中:
<div class="far ancestor">
<div class="near ancestor">
<p>Where am I?</p>
</div>
</div>
然后是div。near。祖宗如果我在p上尝试这个,然后搜索祖宗。
当前回答
这招很管用:
function findAncestor (el, cls) {
while ((el = el.parentElement) && !el.classList.contains(cls));
return el;
}
while循环一直等到el拥有所需的类,并在每次迭代中将el设置为el的父类,因此在最后,你就有了该类或null的祖先。
这是小提琴,如果有人想改进的话。它不能在旧的浏览器(即IE)上工作;请看这个兼容性表中的classList。这里使用parentElement,因为parentNode将涉及更多工作,以确保节点是一个元素。
其他回答
更新:现在大多数主流浏览器都支持
document.querySelector("p").closest(".near.ancestor")
注意,这可以匹配选择器,而不仅仅是类
https://developer.mozilla.org/en-US/docs/Web/API/Element.closest
对于不支持nearest()但有matches()的旧浏览器,可以构建类似于@rvighne的类匹配的选择器匹配:
function findAncestor (el, sel) {
while ((el = el.parentElement) && !((el.matches || el.matchesSelector).call(el,sel)));
return el;
}
@rvighne解决方案工作得很好,但正如评论中所指出的,ParentElement和ClassList都有兼容性问题。为了使它更加兼容,我使用了:
function findAncestor (el, cls) {
while ((el = el.parentNode) && el.className.indexOf(cls) < 0);
return el;
}
parentNode属性而不是parentElement属性 className属性上的indexOf方法,而不是classList属性上的contains方法。
当然,indexOf只是查找该字符串是否存在,它并不关心它是否是整个字符串。因此,如果您有另一个具有'祖宗类型'类的元素,它仍然会返回为已找到'祖宗',如果这对您来说是一个问题,也许您可以使用regexp来找到精确匹配。
此解决方案应该适用于IE9及以上版本。
它就像jQuery的parents()方法,当你需要获得一个父容器时,它可能比给定的元素高几层,比如找到一个点击的<按钮>的包含<表单>。遍历父类,直到找到匹配的选择器,或者直到它到达<body>。返回匹配的元素或<body>。
function parents(el, selector){
var parent_container = el;
do {
parent_container = parent_container.parentNode;
}
while( !parent_container.matches(selector) && parent_container !== document.body );
return parent_container;
}
这招很管用:
function findAncestor (el, cls) {
while ((el = el.parentElement) && !el.classList.contains(cls));
return el;
}
while循环一直等到el拥有所需的类,并在每次迭代中将el设置为el的父类,因此在最后,你就有了该类或null的祖先。
这是小提琴,如果有人想改进的话。它不能在旧的浏览器(即IE)上工作;请看这个兼容性表中的classList。这里使用parentElement,因为parentNode将涉及更多工作,以确保节点是一个元素。
使用element.closest ()
https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
请看这个例子DOM:
<article>
<div id="div-01">Here is div-01
<div id="div-02">Here is div-02
<div id="div-03">Here is div-03</div>
</div>
</div>
</article>
下面是使用element. nearest的方法:
var el = document.getElementById('div-03');
var r1 = el.closest("#div-02");
// returns the element with the id=div-02
var r2 = el.closest("div div");
// returns the closest ancestor which is a div in div, here is div-03 itself
var r3 = el.closest("article > div");
// returns the closest ancestor which is a div and has a parent article, here is div-01
var r4 = el.closest(":not(div)");
// returns the closest ancestor which is not a div, here is the outmost article