다음 일치하는 형제를 찾는 효율적이고 간결한 방법?
공식 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
무엇이든, 핸들러)와 선택 "div.foo"를 일치하는 다음 형제 사업부를 찾으려면,이 작업을 수행 할 수 있습니다 :
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
. 모든 것을 Sizzle에 넘길 수 있으며 Sizzle은 완전히 최적화되었습니다. 위의 순진한 루프는 모든 종류의 임시 객체를 만들고 버리며 매번 선택기를 다시 구문 분석해야합니다. 느리다는 것은 놀라운 일이 아닙니다.
물론 :first
끝까지 던질 수는 없습니다 .
jQuery.fn.nextMatching = function(selector) {
return this.nextAll(selector + ":first"); // <== WRONG
};
... 왜냐하면 "div.foo"와 같은 간단한 선택자에서는 작동하지만 "div.foo, div.bar"와 같이 내가 말한 "여러 가지 중 하나"옵션에서는 실패합니다.
편집 : 죄송합니다. 마지막으로 결과 .nextAll()
를 사용 하고 사용할 수 .first()
있지만 jQuery는 첫 번째 형제를 찾기 위해 모든 형제를 방문해야합니다. 전체 목록을 살펴 보지 않고 일치하는 경우 중지하여 모든 결과를 버리고 첫 번째 결과 만 버리고 싶습니다. ( 정말 빠르게 발생하는 것처럼 보이지만 앞서 링크 된 속도 비교 에서 마지막 테스트 사례를 참조하십시오 .)
미리 감사드립니다.
다음 과 같이 다중 선택기 를 전달 하고 결과에 .nextAll()
사용할 수 있습니다 .first()
.
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>
Note, Not yet added to or tried at comparison test. Not certain if actually more efficient than .nextAll()
implementation. Piece attempts to parse selector string argument having multiple comma-separated selector
's . Returns .first()
element of single or comma-separated selectors provided as argument , or this
element if no selector
argument provided to .nextMatchTest()
. Appear to return same results at chrome 37 , ie11
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
'Development Tip' 카테고리의 다른 글
IE 호환 모드를 프로그래밍 방식으로 비활성화하려면 어떻게합니까? (0) | 2020.10.19 |
---|---|
인텔 마이크로 코드 란 무엇입니까? (0) | 2020.10.19 |
“git commit --amend”에서 커밋 메시지 단계를 건너 뛰는 방법은 무엇입니까? (0) | 2020.10.19 |
모듈 대 네임 스페이스-가져 오기 및 Typescript 필요 (0) | 2020.10.19 |
C / C ++에서 서명 된 오버플로 감지 (0) | 2020.10.19 |