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&#xFF1A;

 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效果很好,但是在注释ParentElementClassList都有兼容性问题。 为了使它更加兼容,我使用了:

 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一个完全匹配。