다음에 어울리는 형제를 찾는 효율적이고 간결한 방법?
공식적인 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
(아마도)click
handler, 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
'itsource' 카테고리의 다른 글
안드로이드에서 애니메이션 없이 활동을 전환하는 방법? (0) | 2023.10.29 |
---|---|
왜 탈참조를 가리켜 탈참조라고 합니까? (0) | 2023.10.29 |
jQuery .hasClass() vs.is() (0) | 2023.10.29 |
PACKET_MMAP 및 PACKET_TX_RING을 사용한 데이터 전송 속도가 "정상"보다 느림(없음) (0) | 2023.10.29 |
도커 파일을 사용하여 로컬 wp-content 파일을 Wordpress 컨테이너에 복사하는 방법 (0) | 2023.10.29 |