3 votes

Problèmes avec setTimeout() dans jQuery .each

Le code suivant ne fonctionnera pas correctement. J'ai essayé différentes variations et j'ai cherché partout, mais sans succès.

i = 1;
var timer = new Array();
jQuery('a').each(function($) {
    i++;
    timer[i] = setTimeout(jQuery(this).remove(), i * 5000)
})

8voto

Bon Espresso Points 693

Enveloppez l'élément de suppression avec une fonction

i = 1;
var timer = new Array();
jQuery('a').each(function($) {
    i++;
    var thiz = jQuery(this);
    timer[i] = setTimeout(function() { thiz.remove(); }, i * 5000);
})

4voto

nnnnnn Points 70578

Le premier paramètre de setTimeout (ou setInterval ) doit être une référence à une fonction (ou une chaîne, mais vous ne voulez pas utiliser la syntaxe des chaînes).

Au lieu de passer une fonction en tant que paramètre, vous appelez une fonction et passez son résultat. Si vous enlevez les parenthèses, vous passerez une référence à la fonction :

timer[i] = setTimeout(jQuery(this).remove, i * 5000) 

Mais alors vous commencerez à avoir des problèmes avec this étant la mauvaise chose au moment où la fonction s'exécute réellement. Essayez quelque chose comme ça :

var i = 1,
    timer = [];
jQuery('a').each(function($) {
    i++;
    var $this = jQuery(this);
    timer[i] = setTimeout(function() {$this.remove();}, i * 5000)
})

Cela permet de tirer parti du fonctionnement des fermetures en ce sens que la fonction anonyme transmise à setTimeout aura accès à la $this au moment où il est exécuté, même si la fonction dans laquelle il est exécuté n'a pas été modifiée. $this est déclaré aura fini de s'exécuter à ce moment-là.

Notez qu'il est préférable de déclarer les tableaux avec l'option [] que new Array() .

Notez également que vous initialisez i à 1, puis l'incrémenter avant de l'utiliser de sorte que le premier élément que vous ajoutez à votre tableau sera timer[2] . Vous devriez probablement l'initialiser à 0 et l'incrémenter après le réglage de chaque minuterie.

3voto

James Montagne Points 44517

Felix a déjà fait allusion à la question dans les commentaires, mais je vais développer.

timer[i] = setTimeout(jQuery(this).remove(), i * 5000)

Votre problème réside dans le fait que vous invoquez jQuery(this).remove() et en passant la valeur de retour de cette dernière à votre setTimeout . L'hypothèse est que vous avez l'intention d'exécuter cette fonction à l'expiration du délai. Si c'est le cas, vous devez envelopper cette fonction dans une fonction, de sorte que cette fonction soit transmise à setTimeout et exécuté à l'expiration de la temporisation.

var $el = jQuery(this);

timer[i] = setTimeout(function(){
    $el.remove()
}, i * 5000)

0voto

al01 Points 96

Essayez :

<html>
<body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<a href="#">a</a>
<a href="#">a</a>
<a href="#">a</a>
<a href="#">a</a>
<a href="#">a</a>
<a href="#">a</a>
<script>
i = 1;
var timer = new Array();
    jQuery('a').each(function($) {
    i++;
    timer[i] = setTimeout(jQuery.proxy(function(){jQuery(this).remove();},this), i * 500);
})
</script>
</body>
</html>

-1voto

NoName13 Points 96

setTimeout accepte les déclarations javascript et non la valeur de retour de jQuery(this).remove() :P Voir ce lien

Vous pouvez juste function(){stuff} mais je ne sais pas si jQuery(this) sera traité quand vous le souhaitez.

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