jQuery: Czy mogę wywołać funkcję delay () między addClass () a takimi?

178

Coś tak prostego, jak:

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

nie wydaje się działać. Jaka byłaby najłatwiejsza alternatywa?

serg
źródło
10
chciałem zrobić dokładnie to samo. Fajnie byłoby zadzwonić$("#div").addClassTemporarily("error",1000)
Sebastien Lorber

Odpowiedzi:

365

Możesz utworzyć nową pozycję w kolejce, aby usunąć klasę:

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

Lub używając metody usuwania z kolejki :

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

Powodem, dla którego musisz zadzwonić nextlub dequeuejest to, aby powiadomić jQuery, że skończyłeś z tym elementem w kolejce i że powinien przejść do następnego.

PetersenDidIt
źródło
3
Podoba mi się ta opcja, ponieważ ułatwia ona przekazanie odwołania do obiektu jquery, który jest używany w funkcji kolejkowej, dzięki czemu może być używany w bardziej ogólnym kontekście (bez nazw zakodowanych na stałe).
GrandmasterB
5
Po co nam „następny”? Czy możemy zrobić $ ("# div"). AddClass ("error"). Delay (1000) .queue (function () {$ (this) .removeClass ("error");}); Wydaje się bardziej eleganckie?
Vennsoh,
@Vennsoh Nie musisz przekazywać „następnej” pozycji w kolejce. Możesz zamiast tego użyć
gfullam.
49

AFAIK, metoda opóźnienia działa tylko w przypadku numerycznych modyfikacji CSS.

Do innych celów JavaScript zawiera metodę setTimeout:

window.setTimeout(function(){$("#div").removeClass("error");}, 1000);
Jaspis
źródło
11
+1: Nie używaj Jquery ze względu na Jquery. Istnieją proste rozwiązania wielu problemów w języku JavaScript.
Joel
1
+1: Tak samo jak pierwszy komentarz. Prosty JS również czasami działa dobrze.
wowpatrick
1
+1 dla uproszczenia, ale również dało +1 zaakceptowanej odpowiedzi - ponieważ wskazało mi, że .queue () w rzeczywistości przekazuje obiekt kontynuacji, który należy wywołać ręcznie ('next ()'). Spędziłem pół godziny na zastanawianiu się, dlaczego mój łańcuch bezparametrowych wywołań zwrotnych wykonuje tylko pierwszy - wiele przykładów na innych witrynach używa pojedynczego opóźnienia w łańcuchu i bezparametrowego wywołania zwrotnego, co jest nieco mylącym uproszczeniem tego mechanizmu
quetzalcoatl
1
Tylko pedant uwaga: setTimeout pochodzi z obiektu okna przeglądarki (BOM). JavaScript (rozumiany jako ECMA Script) nie ma tej metody.
corbacho
9

Wiem, że to bardzo stary post, ale połączyłem kilka odpowiedzi w funkcję opakowującą jQuery, która obsługuje łączenie. Mam nadzieję, że to komuś przyniesie korzyści:

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

A oto opakowanie removeClass:

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

Teraz możesz robić takie rzeczy - poczekaj 1sek, dodaj .error, poczekaj 3sek, usuń .error:

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

Piaskownica
źródło
Bardzo pomocne! Dziękuję Ci!
Fabian Jäger
6

Manipulacja CSS jQuery nie jest umieszczana w kolejce, ale możesz ją wykonać wewnątrz kolejki `` fx '', wykonując:

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

Całkiem to samo, co wywołanie setTimeout, ale zamiast tego używa mechanizmu kolejki jQuery.

warpdesign
źródło
To działa lepiej niż zaakceptowana odpowiedź (połączenia nie są powtarzane, jeśli w klasie występuje transformacja przejściowa).
vatavale
4

Oczywiście byłoby łatwiej, gdybyś rozszerzył jQuery w ten sposób:

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

potem możesz użyć tej funkcji, takiej jak addClass:

$('div').addClassDelay('clicked',1000);
user6322596
źródło
1
a jeśli chcesz dodać obsługę łańcuchów, przeczytaj podstawy tworzenia wtyczek lub po prostu dodaj return thisdo funkcji ...
user6322596
2

Opóźnienie działa na kolejce. i o ile wiem, manipulacja css (inna niż przez animate) nie jest w kolejce.

prodigitalson
źródło
2

delaynie działa na żadnej funkcji kolejki, więc powinniśmy użyć setTimeout().

I nie musisz oddzielać rzeczy. Wszystko, co musisz zrobić, to uwzględnić wszystko w setTimeOutmetodzie:

setTimeout(function () {
    $("#div").addClass("error").delay(1000).removeClass("error");
}, 1000);
Alex Jolig
źródło
Nie musisz używać delay () z setTimeout ().
MattYao,
@MattYao Nie sądzę, żebyś rozumiał. Jeśli nie użyjesz setTimeout, to opóźnienie nie zadziała
Alex Jolig,
1
Rozwiązanie nie musi działać razem. Albo użyj delay () z queue () w jQuery, albo po prostu użyj setTimeout (), aby rozwiązać problem. Nie twierdzę, że twoja odpowiedź jest błędna.
MattYao,
0

Spróbuj tego:

function removeClassDelayed(jqObj, c, to) {    
    setTimeout(function() { jqObj.removeClass(c); }, to);
}
removeClassDelayed($("#div"), "error", 1000);
Pablo Martinez
źródło
0

Wypróbuj tę prostą funkcję strzałki:

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

csandreas1
źródło