jQuery: Posso chamar delay () entre addClass () e tal?

178

Algo tão simples como:

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

parece não funcionar. Qual seria a alternativa mais fácil?

serg
fonte
10
queria fazer exatamente a mesma coisa. Seria legal ligar #$("#div").addClassTemporarily("error",1000)
Sebastien Lorber 21/02

Respostas:

365

Você pode criar um novo item de fila para remover a classe:

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

Ou usando o método de deueue :

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

O motivo pelo qual você precisa ligar nextou dequeueé informar ao jQuery que você terminou com esse item na fila e que ele deve passar para o próximo.

PetersenDidIt
fonte
3
Eu gosto dessa opção porque facilita a passagem de uma referência ao objeto jquery usado na função na fila, para que possa ser usado em um contexto mais genérico (sem nomes codificados).
GrandmasterB
5
Por que precisamos do "próximo"? Podemos fazer $ ("# div"). AddClass ("error"). Delay (1000) .queue (function () {$ (this) .removeClass ("error");}); Parece mais elegante?
Vennsoh
@Vennsoh Você não precisa passar um item da fila 'próximo'. Você pode optar por usar o método dequeue (): api.jquery.com/dequeue
gfullam
49

AFAIK, o método de atraso, funciona apenas para modificações numéricas de CSS.

Para outros fins, o JavaScript vem com um método setTimeout:

window.setTimeout(function(){$("#div").removeClass("error");}, 1000);
Jaspe
fonte
11
+1: Não use Jquery por causa de Jquery. Existem soluções javascript simples para muitos problemas.
Joel
1
+1: igual ao primeiro comentário. JS simples também funciona bem algumas vezes.
Wowpatrick
1
+1 por simplicidade, mas também marcou com +1 a resposta aceita - como apontou que o .queue () realmente passa o objeto de continuação que deve ser chamado manualmente (o 'próximo ()'). Passei meia hora me perguntando por que minha cadeia de retornos de chamada sem parâmetros executa apenas o primeiro - muitos exemplos em outros sites usam um único atraso na cadeia e um retorno de chamada sem parâmetros, o que é uma simplificação um pouco enganosa desse mecanismo
quetzalcoatl
1
Apenas uma observação de pedante: setTimeout vem do objeto de janela do navegador (BOM). O JavaScript (entendido como ECMA Script) não possui esse método.
Corbacho # 5/12
9

Eu sei que este é um post muito antigo, mas eu combinei algumas das respostas em uma função de wrapper jQuery que suporta encadeamento. Espero que beneficie alguém:

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

E aqui está um wrapper removeClass:

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

Agora você pode fazer coisas como esta - aguarde 1 segundo, adicione .error, aguarde 3 segundos, remova .error:

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

Caixa de areia
fonte
Muito útil! Obrigado!
Fabian Jäger
6

A manipulação de CSS do jQuery não está na fila, mas você pode executá-la dentro da fila 'fx' fazendo:

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

Exatamente o mesmo que chamar setTimeout, mas usa o mecanismo de fila do jQuery.

warpdesign
fonte
Isso funciona melhor para mim do que para a resposta aceita (as chamadas não se repetem se houver uma transformação de transição na classe).
precisa saber é
4

Obviamente, seria mais simples se você estender o jQuery assim:

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

Depois disso, você pode usar esta função como addClass:

$('div').addClassDelay('clicked',1000);
user6322596
fonte
1
e se você quiser adicionar o encadeamento de suporte, leia te básico sobre Plugin criação, ou simplesmente adicionar return thisà função ...
user6322596
2

O atraso opera em uma fila. e, tanto quanto eu sei, a manipulação de CSS (que não seja através do Animate) não está na fila.

prodigitalson
fonte
2

delaynão funciona em nenhuma função da fila, portanto devemos usá-lo setTimeout().

E você não precisa separar as coisas. Tudo que você precisa fazer é incluir tudo em um setTimeOutmétodo:

setTimeout(function () {
    $("#div").addClass("error").delay(1000).removeClass("error");
}, 1000);
Alex Jolig
fonte
Você não precisa usar delay () com setTimeout ().
MattYao 6/02/19
@ MattYao Acho que você não entendeu a idéia. Se você não usar setTimeout, em seguida, que o atraso não vai funcionar
Alex Jolig
1
A solução não precisa de ambos para trabalhar juntos. O uso de delay () com a fila () no jQuery ou simplesmente o uso de setTimeout () pode resolver o problema. Não estou dizendo que sua resposta está errada.
MattYao 6/02/19
0

Tente o seguinte:

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

Experimente esta simples função de seta:

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

csandreas1
fonte