jQuery: ¿Puedo llamar a delay () entre addClass () y tal?

178

Algo tan simple como:

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

no parece funcionar ¿Cuál sería la alternativa más fácil?

serg
fuente
10
Quería hacer exactamente lo mismo. Sería genial llamar$("#div").addClassTemporarily("error",1000)
Sebastien Lorber

Respuestas:

365

Puede crear un nuevo elemento de la cola para eliminar la clase:

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

O usando el método de eliminación de cola :

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

La razón por la que necesita llamar nexto dequeuees para que jQuery sepa que ha terminado con este elemento en cola y que debe pasar al siguiente.

PetersenDidIt
fuente
3
Me gusta esta opción porque hace que sea fácil pasar una referencia al objeto jquery que se usa en la función en cola, por lo que se puede usar en un contexto más genérico (sin nombres codificados).
GrandmasterB
55
¿Por qué necesitamos "siguiente"? ¿Podemos hacer $ ("# div"). AddClass ("error"). Delay (1000) .queue (function () {$ (this) .removeClass ("error");}); Parece más elegante?
Vennsoh
@Vennsoh No es necesario que pase un elemento de cola 'siguiente'. Puede optar por utilizar el método dequeue () en su lugar: api.jquery.com/dequeue
gfullam
49

AFAIK el método de retraso solo funciona para modificaciones numéricas de CSS.

Para otros fines, JavaScript viene con un método setTimeout:

window.setTimeout(function(){$("#div").removeClass("error");}, 1000);
Jaspe
fuente
11
+1: No uses Jquery por el bien de Jquery. Hay soluciones simples de JavaScript para muchos problemas.
Joel
1
+1: igual que el primer comentario. Simple JS también funciona bien algunas veces.
wowpatrick
1
+1 por simplicidad, pero también +1 'respondió la respuesta aceptada, ya que me señaló que .queue () en realidad pasa un objeto de continuación que debe llamarse manualmente (el' siguiente () '). Pasé media hora preguntándome por qué mi cadena de devoluciones de llamada sin parámetros ejecuta solo la primera: muchos ejemplos en otros sitios usan un solo retraso en la cadena y una devolución de llamada sin parámetros, lo que es un poco engañoso y simplifica demasiado ese mecanismo
quetzalcoatl
1
Solo una nota pedante: setTimeout proviene del objeto de ventana del navegador (BOM). JavaScript (entendido como ECMA Script) no tiene ese método.
corbacho
9

Sé que esta es una publicación muy antigua, pero he combinado algunas de las respuestas en una función de contenedor jQuery que admite el encadenamiento. Espero que beneficie a alguien:

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

Y aquí hay un contenedor removeClass:

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

Ahora puede hacer cosas como esta: espere 1 segundo, agregue .error, espere 3 segundos, elimine .error:

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

Salvadera
fuente
¡Muy útil! ¡Gracias!
Fabian Jäger
6

La manipulación de CSS de jQuery no está en cola, pero puede hacer que se ejecute dentro de la cola 'fx' haciendo:

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

Lo mismo que llamar a setTimeout, pero utiliza el mecanismo de cola de jQuery en su lugar.

diseño warp
fuente
Esto funciona para mí mejor que la respuesta aceptada (las llamadas no se repiten si hay una transformación de transición en la clase).
vatavale
4

Por supuesto, sería más simple si extendiera jQuery de esta manera:

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

después de eso puedes usar esta función como addClass:

$('div').addClassDelay('clicked',1000);
usuario6322596
fuente
1
y si desea agregar soporte de encadenamiento, lea los conceptos básicos sobre la creación de complementos, o simplemente agregue return thisa la función ...
user6322596
2

El retraso opera en una cola. y hasta donde yo sé, la manipulación de CSS (que no sea a través de animado) no está en cola.

prodigitalson
fuente
2

delayno funciona en ninguna función de cola, por lo que deberíamos usar setTimeout().

Y no necesitas separar las cosas. Todo lo que necesitas hacer es incluir todo en un setTimeOutmétodo:

setTimeout(function () {
    $("#div").addClass("error").delay(1000).removeClass("error");
}, 1000);
Alex Jolig
fuente
No tiene que usar delay () con setTimeout ().
MattYao
@MattYao No creo que entiendas la idea. Si no usa setTimeout, entonces ese retraso no funcionará
Alex Jolig
1
La solución no necesita ambos para trabajar juntos. Usar delay () con queue () en jQuery o simplemente usar setTimeout () puede resolver el problema. No digo que tu respuesta sea incorrecta.
MattYao
0

Prueba esto:

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

Prueba esta sencilla función de flecha:

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

csandreas1
fuente