Gibt es bei der offiziellen jQuery-API eine präzisere, aber nicht weniger effiziente Möglichkeit, das nächste Geschwister eines Elements zu finden, das mit einem bestimmten Selektor übereinstimmt, das nicht nextAllmit der :firstPseudoklasse verwendet wird?
Wenn ich offizielle API sage, meine ich, keine Interna zu hacken, direkt zu Sizzle zu gehen, ein Plug-In in den Mix einzufügen usw. (Wenn ich das am Ende tun muss, soll es so sein, aber das ist nicht die Frage. )
ZB bei dieser Struktur:
<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>
Wenn ich ein divIn habe this(vielleicht in einem clickHandler, was auch immer) und das nächste Geschwister-Div finden möchte, das dem Selektor "div.foo" entspricht, kann ich dies tun:
var nextFoo = $(this).nextAll("div.foo:first");
... und es funktioniert (wenn ich zum Beispiel mit "Fünf" beginne, überspringt es "Sechs" und "Sieben" und findet "Acht" für mich), aber es ist klobig und wenn ich mit dem ersten von einem übereinstimmen möchte Bei mehreren Selektoren wird es viel klobiger. (Zugegeben, es ist viel prägnanter als die rohe DOM-Schleife ...)
Ich möchte im Grunde:
var nextFoo = $(this).nextMatching("div.foo");
... wo nextMatchingkann die gesamte Auswahl an Selektoren akzeptiert werden. Ich bin immer überrascht, dass next(selector)dies nicht funktioniert, aber nicht, und in den Dokumenten ist klar, was es tut, also ...
Ich kann es immer schreiben und hinzufügen, obwohl die Dinge ziemlich ineffizient werden, wenn ich das tue und mich an die veröffentlichte API halte. Zum Beispiel eine naivenext Schleife:
jQuery.fn.nextMatching = function(selector) {
var match;
match = this.next();
while (match.length > 0 && !match.is(selector)) {
match = match.next();
}
return match;
};
... ist deutlich langsamer alsnextAll("selector:first") . Und das ist nicht überraschend, nextAllkann das Ganze an Sizzle übergeben, und Sizzle wurde gründlich optimiert. Die naive Schleife oben erzeugt und wirft alle Arten von temporären Objekten weg und muss den Selektor jedes Mal neu analysieren, keine große Überraschung, dass er langsam ist.
Und natürlich kann ich nicht einfach einen :firstam Ende werfen :
jQuery.fn.nextMatching = function(selector) {
return this.nextAll(selector + ":first"); // <== WRONG
};
... weil dies zwar mit einfachen Selektoren wie "div.foo" funktioniert, aber mit der Option "beliebig von mehreren", über die ich gesprochen habe, wie "div.foo, div.bar", fehlschlägt.
Bearbeiten : Entschuldigung, hätte sagen sollen: Schließlich könnte ich nur das Ergebnis verwenden .nextAll()und dann verwenden .first(), aber dann muss jQuery alle Geschwister besuchen, um das erste zu finden. Ich möchte, dass es aufhört, wenn es ein Match gibt, anstatt die vollständige Liste durchzugehen, nur damit alle Ergebnisse außer dem ersten weggeworfen werden können. (Obwohl es sehr schnell zu gehen scheint ; siehe den letzten Testfall im Geschwindigkeitsvergleich zuvor verlinkten .)
Danke im Voraus.
.nextAll().first()?