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?


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.


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);

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');


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.


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);

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.


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);

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);

0

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

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.