itsource

특정 클래스가 있는 가장 가까운 상위 요소 찾기

mycopycode 2022. 11. 5. 17:28
반응형

특정 클래스가 있는 가장 가까운 상위 요소 찾기

순수 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()@selectorighne의 클래스 매칭과 유사한 selector-module을 구축할 수 있습니다.

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

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.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

8472의 답변과 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;
}

@commonighne 솔루션은 정상적으로 동작하지만, 코멘트에 기재되어 있는 바와 같이ParentElement그리고.ClassList둘 다 호환성 문제가 있습니다.호환성을 높이기 위해 다음을 사용했습니다.

function findAncestor (el, cls) {
    while ((el = el.parentNode) && el.className.indexOf(cls) < 0);
    return el;
}
  • parentNode의 대신parentElement소유물
  • indexOf의 메서드className의 대신contains의 메서드classList소유물.

물론 indexOf는 단순히 해당 문자열의 존재 여부를 찾고 있을 뿐이며 전체 문자열인지 여부는 중요하지 않습니다.따라서 클래스가 'anester-type'인 다른 요소가 있는 경우에도 'anester'를 찾은 것으로 반환됩니다. 문제가 있는 경우 regexp를 사용하여 정확한 일치를 찾을 수 있습니다.

이 솔루션은 IE9 이상에서 동작합니다.

이것은 jQuery의 parents() 메서드와 같은 방법으로, 예를 들어 containing container를 특정 요소에서 몇 레벨 업할 수 있는 부모 컨테이너를 취득할 필요가 있습니다.<form>클릭된<button>일치하는 셀렉터가 발견될 때까지 또는 일치하는 셀렉터가 에 도달할 때까지 부모로부터 조사합니다.<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;
}

언급URL : https://stackoverflow.com/questions/22119673/find-the-closest-ancestor-element-that-has-a-specific-class

반응형