jQuery: Kann ich delay () zwischen addClass () und so aufrufen?

178

Etwas so Einfaches wie:

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

scheint nicht zu funktionieren. Was wäre die einfachste Alternative?

serg
quelle
10
wollte genau das Gleiche tun. Es wäre cool anzurufen$("#div").addClassTemporarily("error",1000)
Sebastien Lorber

Antworten:

365

Sie können ein neues Warteschlangenelement erstellen, um die Klasse zu entfernen:

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

Oder mit der Dequeue- Methode:

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

Der Grund, warum Sie anrufen müssen nextoder dequeuemöchten, besteht darin, jQuery mitzuteilen, dass Sie mit diesem Element in der Warteschlange fertig sind und dass es mit dem nächsten fortfahren soll.

PetersenDidIt
quelle
3
Ich mag diese Option, weil es einfach ist, einen Verweis auf das in der Warteschlangenfunktion verwendete jquery-Objekt zu übergeben, sodass es in einem allgemeineren Kontext (ohne fest codierte Namen) verwendet werden kann.
Großmeister
5
Warum brauchen wir "weiter"? Können wir $ ("# div"). AddClass ("error"). Delay (1000) .queue (function () {$ (this) .removeClass ("error");}); Scheint eleganter?
Vennsoh
@Vennsoh Sie müssen kein 'nächstes' Warteschlangenelement übergeben. Sie können stattdessen die Methode dequeue () verwenden: api.jquery.com/dequeue
gfullam
49

AFAIK Die Verzögerungsmethode funktioniert nur für numerische CSS-Änderungen.

Für andere Zwecke wird JavaScript mit einer setTimeout-Methode geliefert:

window.setTimeout(function(){$("#div").removeClass("error");}, 1000);
Jaspis
quelle
11
+1: Benutze Jquery nicht um Jquerys willen. Es gibt einfache Javascript-Lösungen für viele Probleme.
Joel
1
+1: Genau wie der erste Kommentar. Simple JS funktioniert manchmal auch gut.
Wowpatrick
1
Der Einfachheit halber +1, aber auch +1 die akzeptierte Antwort - da es mich darauf hinwies, dass die .queue () tatsächlich ein Fortsetzungsobjekt übergibt, das manuell aufgerufen werden muss (das 'next ()'). Ich habe mich eine halbe Stunde lang gefragt, warum meine Kette von parameterlosen Rückrufen nur den ersten ausführt - viele Beispiele auf anderen Websites verwenden eine einzelne Verzögerung in der Kette und einen parameterlosen Rückruf, was eine etwas irreführende Vereinfachung dieses Mechanismus darstellt
quetzalcoatl
1
Nur eine Anmerkung des Pedanten: setTimeout stammt aus dem Fensterobjekt (BOM) des Browsers. JavaScript (als ECMA-Skript verstanden) verfügt nicht über diese Methode.
Corbacho
9

Ich weiß, dass dies ein sehr alter Beitrag ist, aber ich habe einige der Antworten in einer jQuery-Wrapper-Funktion zusammengefasst, die die Verkettung unterstützt. Hoffe, es kommt jemandem zugute:

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

Und hier ist ein removeClass-Wrapper:

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

Jetzt können Sie solche Dinge tun - 1 Sekunde warten, hinzufügen .error, 3 Sekunden warten, entfernen .error:

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

Sandkasten
quelle
Sehr hilfreich! Danke dir!
Fabian Jäger
6

Die CSS-Manipulation von jQuery wird nicht in die Warteschlange gestellt. Sie können sie jedoch in der Warteschlange 'fx' ausführen, indem Sie Folgendes tun:

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

Ganz genauso wie beim Aufrufen von setTimeout, verwendet jedoch stattdessen den Warteschlangenmechanismus von jQuery.

Warpdesign
quelle
Dies funktioniert für mich besser als akzeptierte Antwort (Aufrufe werden nicht wiederholt, wenn es in der Klasse eine Übergangstransformation gibt).
Vatavale
4

Natürlich wäre es einfacher, wenn Sie jQuery wie folgt erweitern:

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

Danach können Sie diese Funktion wie addClass verwenden:

$('div').addClassDelay('clicked',1000);
user6322596
quelle
1
und wenn Sie Verkettungsunterstützung hinzufügen möchten, lesen Sie die Grundlagen zur Plugin-Erstellung oder fügen Sie einfach return thisdie Funktion hinzu ...
user6322596
2

Die Verzögerung wird in einer Warteschlange ausgeführt. und soweit ich weiß, ist die CSS-Manipulation (außer durch Animieren) nicht in der Warteschlange.

prodigitalson
quelle
2

delayfunktioniert nicht mit Funktionen ohne Warteschlange, daher sollten wir verwenden setTimeout().

Und Sie müssen keine Dinge trennen. Alles, was Sie tun müssen, ist, alles in eine setTimeOutMethode aufzunehmen:

setTimeout(function () {
    $("#div").addClass("error").delay(1000).removeClass("error");
}, 1000);
Alex Jolig
quelle
Sie müssen delay () nicht mit setTimeout () verwenden.
MattYao
@ MattYao Ich glaube nicht, dass du auf die Idee kommst. Wenn Sie setTimeout nicht verwenden, funktioniert diese Verzögerung nicht
Alex Jolig
1
Die Lösung muss nicht beides zusammenarbeiten. Verwenden Sie entweder delay () mit queue () in jQuery oder verwenden Sie einfach setTimeout (), um das Problem zu lösen. Ich sage nicht, dass Ihre Antwort falsch ist.
MattYao
0

Versuche dies:

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

Probieren Sie diese einfache Pfeilfunktion aus:

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

csandreas1
quelle