find具有特定类的最接近的祖先元素
我怎么能find一个元素的祖先是最接近具有特定类的树, 在纯粹的JavaScript ? 例如,像这样的树:
<div class="far ancestor"> <div class="near ancestor"> <p>Where am I?</p> </div> </div>
那么我想要div.near.ancestor
如果我在p
上尝试这个并寻找ancestor
。
这是诀窍:
function findAncestor (el, cls) { while ((el = el.parentElement) && !el.classList.contains(cls)); return el; }
while循环一直等到el
有所需的类,并且每次迭代都会将el
设置为el
的父元素,所以最后,您将拥有该类的祖先或null
。
这是一个小提琴 ,如果有人想改善它。 它不适用于旧的浏览器(即IE); 请参阅classList的兼容性表 。 这里使用了parentElement
,因为parentNode
会涉及更多的工作来确保节点是一个元素。
更新:现在在大多数主stream浏览器都支持
document.querySelector("p").closest(".near.ancestor")
请注意,这可以匹配select器,而不仅仅是类
https://developer.mozilla.org/en-US/docs/Web/API/Element.closest
对于不支持closest()
但具有matches()
传统浏览器,可以构build类似于@ rvighne类匹配的select器匹配:
function findAncestor (el, sel) { while ((el = el.parentElement) && !((el.matches || el.matchesSelector).call(el,sel))); return el; }
基于8472的回答和https://developer.mozilla.org/pl/docs/Web/API/Element/matches这里是跨平台的2017解决scheme:;
if (!Element.prototype.matches) { Element.prototype.matches = Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector || function(s) { var matches = (this.document || this.ownerDocument).querySelectorAll(s), i = matches.length; while (--i >= 0 && matches.item(i) !== this) {} return i > -1; }; } function findAncestor(el, sel) { if (typeof el.closest === 'function') { return el.closest(sel) || null; } while (el) { if (el.matches(sel)) { return el; } el = el.parentElement; } return null; }
@rvighne解决scheme效果很好,但是在注释ParentElement
和ClassList
都有兼容性问题。 为了使它更加兼容,我使用了:
function findAncestor (el, cls) { while ((el = el.parentNode) && el.className.indexOf(cls) < 0); return el; }
-
parentNode
属性而不是parentElement
属性 -
className
属性上的indexOf
方法,而不是classList
属性上的contains
方法。
当然,indexOf只是简单地寻找那个string的存在,它并不关心它是否是整个string。 所以,如果你有另外一个类的祖先types的元素,它仍然会返回find“祖先”,如果这是你的问题,也许你可以使用正则expression式来find一个完全匹配。