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?

serg
la source
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.

PetersenDidIt
la source
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);
Jaspe
la source
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');

bac à sable
la source
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.

déformation
la source
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);
user6322596
la source
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.

prodigitalson
la source
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);
Alex Jolig
la source
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);
Pablo Martinez
la source
0

Essayez cette simple fonction de flèche:

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

csandreas1
la source