순수 JavaScript에서 특정 클래스가있는 트리에 가장 가까운 요소의 조상을 어떻게 찾을 수 있습니까? 예를 들어, 다음과 같은 나무에서 :
<div class="far ancestor">
<div class="near ancestor">
<p>Where am I?</p>
</div>
</div>
그런 다음에 이것을 div.near.ancestor
시도 p
하고를 검색 하고 싶습니다 ancestor
.
답변
업데이트 : 대부분의 주요 브라우저에서 지원
document.querySelector("p").closest(".near.ancestor")
이것은 클래스뿐만 아니라 선택기와 일치 할 수 있습니다.
https://developer.mozilla.org/en-US/docs/Web/API/Element.closest
지원하지 closest()
않지만 가지고있는 레거시 브라우저 matches()
의 경우 @rvighne의 클래스 일치와 유사한 선택기 일치를 만들 수 있습니다.
function findAncestor (el, sel) {
while ((el = el.parentElement) && !((el.matches || el.matchesSelector).call(el,sel)));
return el;
}
답변
이것은 트릭을 수행합니다.
function findAncestor (el, cls) {
while ((el = el.parentElement) && !el.classList.contains(cls));
return el;
}
때까지 루프 대기하면서 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.closest를 사용하는 방법입니다.
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
답변
the8472 답변 과 https://developer.mozilla.org/en-US/docs/Web/API/Element/matches를 기반으로 여기에 크로스 플랫폼 2017 솔루션이 있습니다.
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 솔루션은 잘 작동하지만, 코멘트에 식별 ParentElement
하고 ClassList
모두 호환성 문제가 있습니다. 호환성을 높이기 위해 다음을 사용했습니다.
function findAncestor (el, cls) {
while ((el = el.parentNode) && el.className.indexOf(cls) < 0);
return el;
}
parentNode
속성 대신parentElement
속성indexOf
온 방법className
대신에 재산contains
상의 방법classList
속성입니다.
물론 indexOf는 단순히 해당 문자열의 존재를 찾고 있으며 전체 문자열인지 여부를 신경 쓰지 않습니다. 따라서 클래스 ‘ancestor-type’이있는 다른 요소가있는 경우 여전히 ‘조상’을 찾은 것으로 반환됩니다.이 문제가있는 경우 regexp를 사용하여 정확하게 일치하는 것을 찾을 수 있습니다.