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 nextAll
mit der :first
Pseudoklasse 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 div
In habe this
(vielleicht in einem click
Handler, 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 nextMatching
kann 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, nextAll
kann 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 :first
am 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()
?