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.
InformationsquelleAutor T.J. Crowder | 2011-02-08