jQuery: я могу вызвать delay () между addClass () и тому подобное?

178

Что-то простое, как:

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

не похоже на работу. Что будет самой простой альтернативой?

Serg
источник
10
хотел сделать точно так же. Было бы здорово позвонить$("#div").addClassTemporarily("error",1000)
Себастьян Лорбер

Ответы:

365

Вы можете создать новый элемент очереди для удаления класса:

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

Или используя метод dequeue :

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

Причина, по которой вам нужно позвонить nextили dequeueсообщить jQuery, что вы закончили с этим элементом в очереди и что он должен перейти к следующему.

PetersenDidIt
источник
3
Мне нравится эта опция, потому что она позволяет легко передавать ссылку на объект jquery, который используется в функции с очередями, поэтому ее можно использовать в более общем контексте (без жестко закодированных имен).
GrandmasterB
5
Зачем нам «следующий»? Можем ли мы сделать $ ("# div"). AddClass ("error"). Delay (1000) .queue (function () {$ (this) .removeClass ("error");}); Кажется более элегантным?
Vennsoh
@Vennsoh Вам не нужно пропускать следующий элемент очереди. Вместо этого вы можете использовать метод dequeue (): api.jquery.com/dequeue
gfullam
49

AFAIK метод задержки работает только для числовых модификаций CSS.

Для других целей JavaScript поставляется с методом setTimeout:

window.setTimeout(function(){$("#div").removeClass("error");}, 1000);
Джаспер
источник
11
+1: не используйте Jquery ради Jquery. Есть простые javascript решения многих проблем.
Джоэл
1
+1: так же, как первый комментарий. Простой JS также отлично работает несколько раз.
wowpatrick
1
+1 для простоты, но также +1 принял принятый ответ - поскольку он указал мне, что .queue () фактически пропускает объект продолжения, который должен быть вызван вручную ('next ()'). Я потратил полчаса на размышления, почему моя цепочка обратных вызовов без параметров выполняет только первый - во многих примерах на других сайтах используется одиночная задержка в цепочке и обратный вызов без параметров, что немного вводит в заблуждение упрощение этого механизма
quetzalcoatl
1
Просто примечание педанта: setTimeout происходит из объекта окна браузера (BOM). JavaScript (понимаемый как скрипт ECMA) не имеет такого метода.
Корбахо
9

Я знаю, что это очень старая статья, но я объединил несколько ответов в функцию-обертку jQuery, которая поддерживает связывание. Надеюсь, это кому-то выгодно:

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

А вот обертка removeClass:

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

Теперь вы можете делать такие вещи - подождите 1сек, добавьте .error, подождите 3сек, удалите .error:

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

песочница
источник
Очень полезно! Спасибо!
Фабиан Ягер
6

CSS-манипуляции jQuery не ставятся в очередь, но вы можете выполнить их внутри очереди 'fx', выполнив:

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

То же самое, что и вызов setTimeout, но вместо этого используется механизм очереди jQuery.

warpdesign
источник
Это работает для меня лучше, чем принятый ответ (вызовы не повторяются, если в классе есть переходное преобразование).
vatavale
4

Конечно, было бы проще, если бы вы расширили jQuery следующим образом:

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

после этого вы можете использовать эту функцию как addClass:

$('div').addClassDelay('clicked',1000);
user6322596
источник
1
и если вы хотите добавить поддержку цепочки, прочитайте основы создания плагинов или просто добавьте return thisв функцию ...
user6322596
2

Задержка работает в очереди. и, насколько я знаю, манипуляции css (кроме как через анимацию) не ставятся в очередь.

prodigitalson
источник
2

delayне работает ни с одной из функций очереди, поэтому мы должны использовать setTimeout().

И вам не нужно разделять вещи. Все, что вам нужно сделать, это включить все в setTimeOutметод:

setTimeout(function () {
    $("#div").addClass("error").delay(1000).removeClass("error");
}, 1000);
Алекс Джолиг
источник
Вам не нужно использовать delay () с setTimeout ().
MattYao
@ MattYao Я не думаю, что вы поняли идею. Если вы не используете setTimeout, то эта задержка не сработает
Алекс Джолиг
1
Решение не нуждается в обоих для совместной работы. Либо используйте delay () с queue () в jQuery, либо просто используйте setTimeout (), чтобы решить эту проблему. Я не говорю, что ваш ответ неверен.
MattYao
0

Попробуй это:

function removeClassDelayed(jqObj, c, to) {    
    setTimeout(function() { jqObj.removeClass(c); }, to);
}
removeClassDelayed($("#div"), "error", 1000);
Пабло Мартинес
источник
0

Попробуйте эту простую функцию стрелки:

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

csandreas1
источник