jQuery: Puis-je appeler delay () entre addClass () et autres?


178

Quelque chose d'aussi simple que:

$("#div").addClass("error").delay(1000).removeClass("error");

ne semble pas fonctionner. Quelle serait l'alternative la plus simple?


10
voulait faire exactement la même chose. Ce serait cool d'appeler$("#div").addClassTemporarily("error",1000)
Sebastien Lorber

Réponses:


365

Vous pouvez créer un nouvel élément de file d'attente pour supprimer la classe:

$("#div").addClass("error").delay(1000).queue(function(next){
    $(this).removeClass("error");
    next();
});

Ou en utilisant la méthode de file d'attente :

$("#div").addClass("error").delay(1000).queue(function(){
    $(this).removeClass("error").dequeue();
});

La raison pour laquelle vous devez appeler nextou dequeueest pour faire savoir à jQuery que vous avez terminé avec cet élément en file d'attente et qu'il doit passer au suivant.


3
J'aime cette option car elle permet de passer facilement une référence à l'objet jquery qui est utilisé dans la fonction en file d'attente, afin de pouvoir l'utiliser dans un contexte plus générique (sans noms codés en dur).
GrandmasterB

5
Pourquoi avons-nous besoin de «suivant»? Pouvons-nous faire $ ("# div"). AddClass ("erreur"). Delay (1000) .queue (function () {$ (this) .removeClass ("error");}); Semble plus élégant?
Vennsoh

@Vennsoh Vous n'avez pas besoin de passer un élément de file d'attente «suivant». Vous pouvez choisir d'utiliser la méthode dequeue
gfullam

49

AFAIK la méthode de délai ne fonctionne que pour les modifications CSS numériques.

À d'autres fins, JavaScript est fourni avec une méthode setTimeout:

window.setTimeout(function(){$("#div").removeClass("error");}, 1000);

11
+1: N'utilisez pas Jquery pour Jquery. Il existe des solutions javascript simples à de nombreux problèmes.
Joel

1
+1: identique au premier commentaire. Simple JS fonctionne également très bien quelques fois.
wowpatrick

1
+1 pour simplifier, mais aussi +1 pour la réponse acceptée - car elle m'a fait remarquer que le .queue () passe en fait l'objet de continuation qui doit être appelé manuellement (le 'next ()'). J'ai passé une demi-heure à me demander pourquoi ma chaîne de rappels sans paramètre n'exécute que le premier - de nombreux exemples sur d'autres sites utilisent un seul délai dans la chaîne et un rappel sans paramètre, ce qui est une simplification un peu trompeuse de ce mécanisme
quetzalcoatl

1
Juste une note pédante: setTimeout provient de l'objet fenêtre du navigateur (BOM). JavaScript (compris comme ECMA Script) n'a pas cette méthode.
corbacho

9

Je sais que c'est un très vieux message, mais j'ai combiné quelques-unes des réponses dans une fonction wrapper jQuery qui prend en charge le chaînage. J'espère que cela profite à quelqu'un:

$.fn.queueAddClass = function(className) {
    this.queue('fx', function(next) {
        $(this).addClass(className);
        next();
    });
    return this;
};

Et voici un wrapper removeClass:

$.fn.queueRemoveClass = function(className) {
    this.queue('fx', function(next) {
        $(this).removeClass(className);
        next();
    });
    return this;
};

Maintenant, vous pouvez faire des choses comme ça - attendez 1 seconde, ajoutez .error, attendez 3 secondes, supprimez .error:

$('#div').delay(1000).queueAddClass('error').delay(2000).queueRemoveClass('error');


Très utile! Je vous remercie!
Fabian Jäger

6

La manipulation CSS de jQuery n'est pas mise en file d'attente, mais vous pouvez l'exécuter dans la file d'attente 'fx' en faisant:

$('#div').delay(1000).queue('fx', function() { $(this).removeClass('error'); });

Tout à fait la même chose que d'appeler setTimeout mais utilise à la place le mécanisme de file d'attente de jQuery.


Cela fonctionne pour moi mieux que la réponse acceptée (les appels ne se répètent pas s'il y a une transformation de transition en classe).
vatavale

4

Bien sûr, ce serait plus simple si vous étendez jQuery comme ceci:

$.fn.addClassDelay = function(className,delay) {
    var $addClassDelayElement = $(this), $addClassName = className;
    $addClassDelayElement.addClass($addClassName);
    setTimeout(function(){
        $addClassDelayElement.removeClass($addClassName);
    },delay);
};

après cela, vous pouvez utiliser cette fonction comme addClass:

$('div').addClassDelay('clicked',1000);

1
et si vous souhaitez ajouter un support de chaînage, lisez les bases de la création de plugins ou ajoutez simplement return thisà la fonction ...
user6322596

2

Le délai fonctionne sur une file d'attente. et pour autant que je sache, la manipulation css (autre que via animate) n'est pas mise en file d'attente.


2

delayne fonctionne pas sur aucune fonction de file d'attente, nous devrions donc utiliser setTimeout().

Et vous n'avez pas besoin de séparer les choses. Tout ce que vous avez à faire est de tout inclure dans une setTimeOutméthode:

setTimeout(function () {
    $("#div").addClass("error").delay(1000).removeClass("error");
}, 1000);

Vous n'avez pas besoin d'utiliser delay () avec setTimeout ().
MattYao

@MattYao Je ne pense pas que vous compreniez l'idée. Si vous n'utilisez pas setTimeout, alors ce retard ne fonctionnera pas
Alex Jolig

1
La solution n'a pas besoin des deux pour fonctionner ensemble. Soit utiliser delay () avec queue () dans jQuery ou simplement utiliser setTimeout () peut résoudre le problème. Je ne dis pas que votre réponse est fausse.
MattYao

0

Essaye ça:

function removeClassDelayed(jqObj, c, to) {    
    setTimeout(function() { jqObj.removeClass(c); }, to);
}
removeClassDelayed($("#div"), "error", 1000);

0

Essayez cette simple fonction de flèche:

setTimeout( () => { $("#div").addClass("error") }, 900 );

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.