itsource

다음에 어울리는 형제를 찾는 효율적이고 간결한 방법?

mycopycode 2023. 10. 29. 19:43
반응형

다음에 어울리는 형제를 찾는 효율적이고 간결한 방법?

공식적인 jQuery API를 고수하는 것은 다음을 사용하는 것 이외에 주어진 선택기와 일치하는 요소의 다음 형제를 찾는 더 간결하지만 덜 효율적인 방법이 있습니까?nextAll와 함께:first사이비급?

제가 공식 API라고 할 때 내부 해킹, 바로 Sizzle로 이동, 믹스에 플러그인 추가 등을 의미합니다. (만약 제가 그렇게 해야 한다면 그렇게 하세요, 하지만 이 질문은 그게 아닙니다.)

예를 들어, 다음과 같은 구조를 고려할 때:

<div>One</div>
<div class='foo'>Two</div>
<div>Three</div>
<div class='foo'>Four</div>
<div>Five</div>
<div>Six</div>
<div>Seven</div>
<div class='foo'>Eight</div>

만약에 나한테.div인에this(아마도)clickhandler, what)을 선택하고 "div.foo" 선택기와 일치하는 다음 형제 div를 찾고 싶습니다. 제가 할 수 있는 것은 다음과 같습니다.

var nextFoo = $(this).nextAll("div.foo:first");

...그리고 작동합니다(예를 들어 "Five"로 시작하면 "Six"와 "Seven"을 건너뛰고 "Eight"를 찾으면). 하지만 투박하고 여러 선택기 중 첫 번째 선택기와 일치하려면 훨씬 투박해집니다. (물론 원시 DOM 루프보다 훨씬 더 간결합니다.)

저는 기본적으로 다음을 원합니다.

var nextFoo = $(this).nextMatching("div.foo");

...어디에nextMatching셀렉터의 전체 범위를 허용할 수 있습니다.저는 항상 놀랍습니다.next(selector)이런 짓은 안 하지만, 그렇지 않아요 그리고 의사들은 그게 무슨 짓을 하는지 확실히 알고 있으니까요

저는 항상 작성하고 추가할 수 있지만, 그렇게 하고 공개된 API를 고수하면 일이 상당히 비효율적이 됩니다.예를 들면, 순진한 ï브.next루프:

jQuery.fn.nextMatching = function(selector) {
    var match;

    match = this.next();
    while (match.length > 0 && !match.is(selector)) {
        match = match.next();
    }
    return match;
};

...보다 현저하게 느립니다.nextAll("selector:first"). 그리 놀라운 일은 아니지만,nextAll모든 것을 시즐에게 넘겨줄 수 있고, 시즐은 철저히 최적화되어 있습니다.위의 ï브 루프는 모든 종류의 임시 객체를 생성하고 버립니다. 그리고 매번 셀렉터를 다시 파싱해야 하는데, 느리다는 것은 놀라운 일이 아닙니다.

그리고 물론, 저는 그냥 던지지는 못합니다.:first끝에:

jQuery.fn.nextMatching = function(selector) {
    return this.nextAll(selector + ":first"); // <== WRONG
};

...div.foo와 같은 간단한 선택기에서는 작동하지만, "div.foo, div.bar "과 같은 제가 말한 "여러 개 중 하나" 옵션에서는 작동하지 않기 때문입니다.

편집: 죄송합니다. 이렇게 말해야 합니다.마침내, 나는 단지 사용할 수 있었습니다..nextAll()그 다음에 사용합니다..first()결과에 따라, 하지만 jQuery는 단지 첫번째를 찾기 위해 모든 형제자매들을 방문해야 할 것입니다.처음을 제외한 모든 결과를 버릴 수 있도록 전체 목록을 검토하는 것보다 일치하는 결과가 나오면 중단했으면 합니다. (비록 정말 빠르게 발생하는 것 같지만, 앞서 링크된 속도 비교에서 마지막 테스트 사례를 참조하십시오.)

미리 감사드립니다.

다중 선택기를 다음과 같이 결과에 전달하여 사용할 수 있습니다.

var nextFoo = $(this).nextAll("div.foo, div.something, div.else").first();

편집: 비교를 위해 테스트 제품군에 추가되었습니다. http://jsperf.com/jquery-next-loop-vs-nextall-first/2 이 방법은 간단한 방법을 제공하기 때문에 훨씬 더 빠릅니다..nextAll()가능한 경우 네이티브 코드로 선택 해제(모든 현재 브라우저)하고 결과 집합의 첫 번째를 취하는 것만으로...당신이 순수하게 자바스크립트로 할 수 있는 어떤 루프보다도 훨씬 빠릅니다.

사용하는 방법은 어떻습니까?first방법:

jQuery.fn.nextMatching = function(selector) {
    return this.nextAll(selector).first();
}

편집, 업데이트됨

다음 형제 선택기("이전 ~ 형제") 사용

jQuery.fn.nextMatching = function nextMatchTest(selector) {
     return $("~ " + selector, this).first()
};

http://jsperf.com/jquery-next-loop-vs-nextall-first/10

jQuery.fn.nextMatching = function nextMatchTest(selector) {
     return $("~ " + selector, this).first()
};
   var nextFoo = $("div:first").nextMatchTest("div.foo");
   console.log(nextFoo)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>One</div>
<div class='foo'>Two</div>
<div>Three</div>
<div class='foo'>Four</div>
<div>Five</div>
<div>Six</div>
<div>Seven</div>
<div class='goo'>Eight</div>


참고, 비교 테스트에 아직 추가되거나 시도되지 않았습니다.실제로 보다 더 효율적인지는 확실하지 않습니다..nextAll()실행.여러 쉼표로 구분된 선택기 문자열 인수를 구문 분석하려고 시도합니다.selector를 합니다..first()인수로 제공되는 단일 또는 쉼표로 구분된 선택기의 요소 또는this없는 경우 요소selector에 제공된 논변.nextMatchTest() 즉 하는 것으로 . 크롬 37에서 동일한 결과를 반환하는 것처럼 보입니다. 즉, 11.

v2

$.fn.nextMatching = function (selector) {
    var elem = /,/.test(selector) ? selector.split(",") : selector
    , sel = this.selector
    , ret = $.isArray(elem) ? elem.map(function (el) {
        return $(sel + " ~ " + $(el).selector).first()[0]
    }) : $(sel + " ~ " + elem).first();
    return selector ? $(ret) : this
};

$.fn.nextMatching = function (selector) {
    var elem = /,/.test(selector) ? selector.split(",") : selector
    , sel = this.selector
    , ret = $.isArray(elem) ? elem.map(function (el) {
        return $(sel + " ~ " + $(el).selector).first()[0]
    }) : $(sel + " ~ " + elem).first();
    return selector ? $(ret) : this
};

var div = $("div:first")
    , foo = div.nextMatching()
    , nextFoo = div.nextMatching("div.foo")
    , nextFooMultiple = div.nextMatching("div.foo, div.goo");
nextFooMultiple.css("color", "green");
nextFoo.css("color", "blue");
console.log(foo);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>One</div>
<div class='foo'>Two</div>
<div>Three</div>
<div class='foo'>Four</div>
<div>Five</div>
<div>Six</div>
<div>Seven</div>
<div class='goo'>Eight</div>

언급URL : https://stackoverflow.com/questions/4933236/efficient-concise-way-to-find-next-matching-sibling

반응형