JQuery imbriqué.chaque () - continuer / pause

Considérons le code suivant:

    var sentences = [
        'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
        'Vivamus aliquet nisl quis velit ornare tempor.',
        'Cras sit amet neque ante, eu ultrices est.',
        'Integer id lectus id nunc venenatis gravida nec eget dolor.',
        'Suspendisse imperdiet turpis ut justo ultricies a aliquet tortor ultrices.'
    ];

    var words = ['ipsum', 'amet', 'elit'];

    $(sentences).each(function() {
        var s = this;
        alert(s);
        $(words).each(function(i) {
            if (s.indexOf(this) > -1)
            {
                alert('found ' + this);
                return false;
            }
        });
    });

La partie intéressante est la jQuery imbriquée.chacun() en boucle. Selon la documentation , renvoyer false sortira de la boucle (interrompant l'exécution de la boucle-similaire à une instruction de rupture JavaScript normale), et renvoyer non-false arrêtera l'itération en cours et continuera avec l'itération suivante (similaire à une instruction JavaScript continue normale).

Je peux casser ou continuer un jQuery.chacun() sur son propre, mais avec jQuery imbriqué.chacun, j'ai trouvé difficile de sortir de la boucle parent à partir de la boucle enfant. Je pourrais utiliser une valeur booléenne, et la mettre à jour à chaque itération enfant, mais je me demandais s'il y avait un moyen plus facile.

J'ai mis en place un exemple à jsFiddle si vous souhaitez s'amuser avec elle. Cliquez simplement sur le bouton" Test " pour exécuter l'exemple ci-dessus.

TLDR: y a-t-il quelque chose qui ressemble à un Continuer ou à un break étiqueté dans le contexte de jQuery?

40
demandé sur Ryan Kinal 2010-07-16 21:45:23

10 réponses

Vous devriez faire ceci sans jQuery, ce n'est peut-être pas aussi "joli" mais il se passe moins de choses et il est plus facile de faire exactement ce que vous voulez, comme ceci:

var sentences = [
    'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
    'Vivamus aliquet nisl quis velit ornare tempor.',
    'Cras sit amet neque ante, eu ultrices est.',
    'Integer id lectus id nunc venenatis gravida nec eget dolor.',
    'Suspendisse imperdiet turpis ut justo ultricies a aliquet tortor ultrices.'
];

var words = ['ipsum', 'amet', 'elit'];

for(var s=0; s<sentences.length; s++) {
    alert(sentences[s]);
    for(var w=0; w<words.length; w++) {
        if(sentences[s].indexOf(words[w]) > -1) {
            alert('found ' + words[w]);
            return;
        }
    }
}

Vous pouvez l'essayer ici. Je ne suis pas sûr si c'est le comportement exact que vous recherchez, mais maintenant vous n'êtes pas dans une fermeture à l'intérieur d'une fermeture créée par le double .each() et vous pouvez return ou break quand vous voulez dans ce cas.

22
répondu Nick Craver 2010-07-16 17:50:23

Il y a beaucoup de réponses ici. Et c'est vieux, mais c'est pour tous ceux qui viennent ici via google. Dans jQuery chaque fonction

return false; c'est comme break.

Juste

return; c'est comme continue

Ceux-ci vont émuler le comportement de break et continuer.

89
répondu Thihara 2012-10-11 09:17:51

Comme il est indiqué dans le jQuery documentation http://api.jquery.com/jQuery.each/ un return true; est continue; dans une boucle et un return false; est break;

13
répondu Serj Sagan 2012-08-16 15:31:44

Il N'y a pas de moyen propre de le faire et comme @Nick mentionné ci-dessus, il pourrait être plus facile d'utiliser la méthode old school des boucles car vous pouvez contrôler cela. Mais si vous voulez rester avec ce que vous avez, il y a une façon de gérer cela. Je suis sûr que je vais obtenir un peu de chaleur pour celui-ci. Mais...

Une façon de faire ce que vous voulez sans instruction if est de générer une erreur et d'envelopper votre boucle avec un bloc try / catch:

try{
$(sentences).each(function() {
    var s = this;
    alert(s);
    $(words).each(function(i) {
        if (s.indexOf(this) > -1)
        {
            alert('found ' + this);
            throw "Exit Error";
        }
    });
});
}
catch (e)
{
    alert(e)
}

Ok, que la bagarre commence.

8
répondu spinon 2010-07-16 17:55:41

Le problème ici est que si vous pouvez renvoyer false depuis le rappel .each, la fonction .each renvoie elle-même l'objet jQuery. Vous devez donc renvoyer un false aux deux niveaux pour arrêter l'itération de la boucle. De plus, comme il n'y a pas moyen de savoir si le .each interne a trouvé une correspondance ou non, nous devrons utiliser une variable partagée en utilisant une fermeture qui est mise à jour.

Chaque itération interne de words fait référence à la même variable notFound, donc nous avons juste besoin de la mettre à jour quand une correspondance est trouvé, puis le retourner. La fermeture externe a déjà une référence à elle, de sorte qu'elle peut break en cas de besoin.

$(sentences).each(function() {
    var s = this;
    var notFound = true;

    $(words).each(function() {
        return (notFound = (s.indexOf(this) == -1));
    });

    return notFound;
});

Vous pouvez essayer votre exemple ici .

7
répondu Anurag 2010-07-16 18:33:51

Malheureusement non. Le problème ici est que l'itération se produit à l'intérieur des fonctions, donc elles ne sont pas comme des boucles normales. La seule façon de "sortir" d'une fonction est de retourner ou de lancer une exception. Donc oui, l'utilisation d'un drapeau booléen semble être le seul moyen raisonnable de "sortir" de la "boucle"externe.

4
répondu casablanca 2010-07-16 17:50:39

Retour true {[3] } ne fonctionne pas

Return false travailler

found = false;
query = "foo";

$('.items').each(function()
{
  if($(this).text() == query)
  {
    found = true;
    return false;
  }
});
4
répondu misima 2011-03-18 00:23:42

J'ai utilisé un modèle "breakout" pour ceci:

$(sentences).each(function() {
    var breakout;
    var s = this;
    alert(s);
    $(words).each(function(i) {
        if (s.indexOf(this) > -1)
        {
            alert('found ' + this);
            return breakout = false;
        }
    });
    return breakout;
});

Cela fonctionne bien à n'importe quelle profondeur d'imbrication. breakout est un drapeau simple. Il restera undefined à moins que et jusqu'à ce que vous le définissiez sur false (comme je le fais dans ma déclaration de retour comme illustré ci-dessus). Tout ce que vous avez à faire est:

  1. déclarez-le dans votre fermeture la plus externe: var breakout;
  2. ajoutez-le à votre (vos) déclaration (s) return false: return breakout = false
  3. retournez l'évasion dans votre ou vos fermetures extérieures.

Pas trop inélégant, Non? ...fonctionne pour moi de toute façon.

4
répondu joneit 2014-04-02 03:59:32

Confirmer dans la documentation de L'API http://api.jquery.com/jQuery.each / dites:

Nous pouvons casser le $.chaque boucle () à une itération particulière en faisant la fonction de rappel renvoie false. Renvoyer non-false est le même que continuer l'instruction dans une boucle for; elle passera immédiatement à la suivante itération.

Et c'est mon exemple http://jsfiddle.net/r6jqP/

(function($){
    $('#go').on('click',function(){
        var i=0,
            all=0;
        $('li').each(function(){
             all++;
             if($('#mytext').val()=='continue')return true;
             i++;
             if($('#mytext').val()==$(this).html()){
                 return false;
             }
        });
        alert('Iterazione : '+i+' to '+all);
    });
}(jQuery));
3
répondu Leonardo Ciaccio 2013-06-15 12:53:24

Rupture Étiquetée

outerloop:
$(sentences).each(function() 
{
    $(words).each(function(i) 
    {
        break; /* breaks inner loop */
    } 
    $(words).each(function(i)  
    {
        break outerloop; /* breaks outer loop */
    }
}
2
répondu capdragon 2012-05-15 14:29:46