Efficace, concise pour trouver la correspondance de la fratrie?
Coller officielle de jQuery API, est-il plus concis, mais pas moins efficace, plus moyen de trouver le prochain fils de l'élément qui correspond à un sélecteur de donnée autre que l'aide nextAll
avec le :first
pseudo-classe?
Quand je dis officielle de l'API, je ne parle pas de piratage interne, aller directement à Grésiller, ajouter un plug-in dans le mélange, etc. (Si je finis par avoir à faire, ainsi soit-il, mais ce n'est pas ce que cette question est.)
E. g, compte tenu de cette structure:
<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>
Si j'ai un div
dans this
(peut-être dans un click
gestionnaire, peu importe) et que vous voulez trouver le frère suivant div qui correspond le sélecteur sur "div.foo", je peux le faire:
var nextFoo = $(this).nextAll("div.foo:first");
...et ça marche (si je commence avec "Cinq", par exemple, il ignore les "Six" et "Sept" et trouve "Huit" pour moi), mais il est maladroit et si je veux correspondre à la première de plusieurs sélecteurs, il reçoit beaucoup moins agiles. (Certes, c'est un beaucoup plus concis que le brut DOM boucle serait...)
En gros, je veux:
var nextFoo = $(this).nextMatching("div.foo");
...où nextMatching
peut accepter la gamme complète des sélecteurs. Je suis toujours surpris de voir que next(selector)
ne pas le faire, mais il ne l'a pas, et les docs sont claires sur ce qu'il fait, donc...
Je peux toujours l'écrire et de l'ajouter, bien que si je le fais et le bâton à la publication de l'API, les choses deviennent assez inefficace. Par exemple, un naïf next
boucle:
jQuery.fn.nextMatching = function(selector) {
var match;
match = this.next();
while (match.length > 0 && !match.is(selector)) {
match = match.next();
}
return match;
};
...est nettement plus lent que nextAll("selector:first")
. Et ce n'est pas surprenant, nextAll
à la main le tout à Grésiller, et le Grésillement a été complètement optimisé. La naïveté de la boucle ci-dessus crée et lance toutes sortes d'objets temporaires et a de l'analyser à nouveau le sélecteur de tous les temps, pas de grande surprise, c'est lent.
Et bien sûr, je ne peux pas il suffit de jeter un :first
sur la fin:
jQuery.fn.nextMatching = function(selector) {
return this.nextAll(selector + ":first"); //<== WRONG
};
...parce que tout qui va travailler avec les sélecteurs simples comme "div.foo", il échouera avec le "plusieurs" option j'en ai parlé, comme, disons, "div.toto, div.bar".
Modifier: Désolé, aurait dit: Enfin, je pouvais .nextAll()
et ensuite utiliser .first()
sur le résultat, mais alors jQuery aura pour tous les frères et sœurs juste de trouver la première. J'aimerais qu'il s'arrête quand il obtient un match plutôt que de passer par la liste complète juste de sorte qu'il peut jeter tous les résultats, mais le premier. (Bien que cela semble arriver vraiment rapide; voir le dernier cas de test dans le comparaison de la vitesse lié plus tôt.)
Merci d'avance.
- avez-vous jamais trouver un moyen plus rapide de faire ce que
.nextAll().first()
? - Non, cela semble être le meilleur moyen.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez passer une plusieurs sélecteur à
.nextAll()
et l'utilisation.first()
sur le résultat, comme ceci:Edit: Juste pour la comparaison, ici, il est ajouté à la suite de tests: http://jsperf.com/jquery-next-loop-vs-nextall-first/2 Cette approche est donc beaucoup plus rapide parce que c'est une simple combinaison de la remise de la
.nextAll()
sélecteur hors de code natif lorsque cela est possible (chaque navigateur actuel) et il suffit de prendre le premier de l'ensemble de résultats....façon plus rapide que la boucle que vous pouvez faire uniquement en JavaScript..next(selector, true)
ou similaire surcharge de quoi vous parlez, parcourant jusqu'à ce qu'il se trouve plutôt que de retourner si il se trouve, mais il semble que la discussion n'est pas sur la.next()
documentation plus: api.jquery.com/nextnextAll(selector).first()
est certainement à la recherche comme le meilleur de la mise en œuvre denextMatching
qui correspond à mes critères..first()
appels, mais la différence qu'il y en comparaison de tout le reste est infinitésimale, donc j'irais pour le code plus lisible dans ce cas. Cela étant dit, mon exemple n'est pas un plugin...si les gens n'ont pas l'utiliser directement, par tous les moyens aller avec.eq(0)
.Comment sur l'utilisation de l'
first
méthode:Édition, Mise À Jour
Utilisant Suivant les Frères et sœurs Sélecteur (“prev ~ frères et sœurs”)
http://jsperf.com/jquery-next-loop-vs-nextall-first/10
JS:
HTML:
Remarque, Pas encore ajouté ou essayer au test de comparaison. Pas certain si réellement plus efficace que
.nextAll()
mise en œuvre. Pièce tente d'analyser sélecteur argument de chaîne ayant de multiples séparées par des virgulesselector
s'. Retourne.first()
élément unique ou séparée par des virgules des sélecteurs fourni en argument , outhis
élément si aucuneselector
argument fourni à.nextMatchTest()
. Semblent renvoyer les résultats au chrome 37 , ie11v2
JS:
HTML:
~
combinator ne fonctionne pas sur IE). (BTW,$(selector, context)
est susceptible d'aller à un certain point, et il est juste converti à$(context).find(selector)
de toute façon, afin de l'utiliser directement sera un peu le plus rapide.) jsperf.com/jquery-next-loop-vs-nextall-first/11 Mais malheureusement, même si moderne IE ne gère pas elle...selector
n'a jamais été fiable et a été dépréciée en 1.7 et retiré dans 1,9 (même si elle est encore là, c'est une partie de l'intérieur, uniquement là pour soutenirlive
pour la migration plugin).