4 votes

Meilleur moyen d'insérer une "pause" dans une énumération .each

Quelle est la meilleure façon d'insérer une "pause" dans chaque énumération d'un ensemble d'éléments en utilisant la fonction jQuery '.each()' ?

$( '.someClass' ).each( function() {
    $( this ).trigger( 'click' ); //fire some request that appends a new div on the body 
    //wait for div to be appended to the DOM.  perhaps use the pause here
    //execute code once the div has been appended 
});

3voto

cdhowie Points 62253

Techniquement, vous ne pouvez pas le faire comme vous l'avez modélisé dans votre code, car JavaScript est un thread unique et s'exécute généralement sur le thread de l'interface utilisateur du navigateur (ou de l'onglet) - toute mise en veille ou tout retard empêchera le navigateur de redessiner la page et empêchera également l'interaction de l'utilisateur avec la page.

Vous devez faire en sorte que le navigateur invoque périodiquement votre code. Quelque chose comme ceci fera l'affaire :

var objects = $.makeArray($( '.someClass' ));

var callback;

callback = function() {
    var item = objects.shift();

    // Do something with item.

    if (objects.length != 0) {
        setTimeout(callback, 5000);
    }
}

setTimeout(callback, 5000);

Voir un exemple .

Cette solution suppose que vous souhaitez que chaque élément soit traité 5 secondes à partir du moment où le dernier élément a terminé son traitement. Cela signifie que :

  1. Si vous le faites confirm() ou autre pendant le traitement de chaque élément, l'élément suivant sera traité 5 secondes après la fermeture de la boîte de dialogue par l'utilisateur.
  2. Le temps d'exécution total sera de (5000N + T) où N est le nombre d'éléments de la liste initiale, et T le temps total nécessaire pour traiter chaque élément.

Voici une fonction que vous pouvez utiliser qui encapsule cette fonctionnalité :

jQuery.eachWithDelay = function(sequence, delay, callback) {
    var objects = jQuery.makeArray(sequence);

    if (objects.length == 0) {
        return;
    }

    var f;

    f = function() {
        var item = objects.shift();

        if (callback(item) && objects.length != 0) {
            setTimeout(f, delay);
        }
    };

    setTimeout(f, delay);
};

Appelé comme ça :

$.eachWithDelay($('.someClass'), 5000, function(item) {
    // Do something with item

    return true; // Return true to continue iterating, or false to stop.
});

Voir le mise à jour du violon .

0voto

jfriend00 Points 152127

Il n'y a pas de bonne façon de mettre un délai comme celui-là au milieu d'une fonction javascript.

Pour retarder légitimement de 5 secondes le prochain incrément de travail, vous devez acquérir les données dont vous avez besoin pour le travail, diviser le travail en petits morceaux, régler une minuterie de 5 secondes et effectuer un morceau du travail à chaque tic-tac de la minuterie.

Voici un exemple concret d'une façon de le faire : http://jsfiddle.net/jfriend00/tgBYk/

var objList = $('.someClass');
var cntr = 0;
var timeDelay = 5000;

function doNextIteration() {
    $(objList[cntr++]).html(cntr);   // your code here: This is the progress I'm showing in my demo
    if (cntr < objList.length) {
        setTimeout(doNextIteration, timeDelay);
    }
}

if (objList.length > 0) {
    doNextIteration();
}

0voto

3nigma Points 21164

Si vous avez le html como

<div class="someClass">google</div>
<div class="someClass">facebook</div>
<div class="someClass">ARPANET</div>

l'emballer $(document).ready() jsfiddle le fait automatiquement

$(".someClass").each(function(i){

       $(this).delay(i+"1000").fadeOut("slow");

    });

voici le violon http://jsfiddle.net/J6Mw6/1/

vous pouvez régler l'heure de votre choix

ou peut-être que ceci peut aider selon votre question éditée

http://jsfiddle.net/J6Mw6/2/

0voto

digitalbath Points 1868

Si vous devez utiliser .each pour une raison ou une autre, cela vous permettra de vous rapprocher de votre objectif, à condition que vous ne fassiez pas une tonne de travail à chaque itération :

var i = 0;
$( '.someClass' ).each( function() {
    setTimeout((function (el) {
        // do something with 'el'
    })(this), i * 5000);
    i += 1;
});

Mais il serait plus correct (compte tenu de la formulation de votre question) de faire quelque chose comme ceci :

(function() {
    var arr = $('.someclass'),
        i = 0,
        fn = function() {
            var el = arr[i];

            // do something with 'el'

            i += 1;
            if (i < arr.length) {
                setTimeout(fn, 5000);
            }
        };
    fn();
})();

0voto

Javier Buzzi Points 2107

Puisqu'il semble que nous ne faisons que jeter des réponses en l'air, voici les miennes. Pas de chacun ?

function doTheDo(els) {

 if(els.length == 0) return;

 $(els.shift()).click();
 setTimeout(doTheDo, 5000, els);

}

doTheDo($('#errors li' ).toArray()) ;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X