jQuery: Tôi có thể gọi delay () giữa addClass () và như vậy không?


178

Một cái gì đó đơn giản như:

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

dường như không hoạt động. Điều gì sẽ là sự thay thế dễ dàng nhất?


10
muốn làm chính xác điều tương tự. Thật tuyệt khi gọi$("#div").addClassTemporarily("error",1000)
Sebastien Lorber

Câu trả lời:


365

Bạn có thể tạo một mục hàng đợi mới để loại bỏ lớp:

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

Hoặc sử dụng phương pháp dequeue :

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

Lý do bạn cần gọi nexthoặc dequeuelà để cho jQuery biết rằng bạn đã hoàn thành với mục được xếp hàng này và nó sẽ chuyển sang mục tiếp theo.


3
Tôi thích tùy chọn này vì nó giúp dễ dàng chuyển tham chiếu đến đối tượng jquery được sử dụng trong hàm xếp hàng, vì vậy nó có thể được sử dụng trong ngữ cảnh chung hơn (không có tên mã hóa cứng).
GrandmasterB

5
Tại sao chúng ta cần "tiếp theo"? Chúng ta có thể làm $ ("# div"). AddClass ("error"). Delay (1000) .queue (function () {$ (this) .removeClass ("error");}); Có vẻ thanh lịch hơn?
Vennsoh

@Vennsoh Bạn không cần phải vượt qua mục hàng đợi 'tiếp theo'. Bạn có thể chọn sử dụng phương thức dequeue () thay thế: api.jquery.com/dequeue
gfullam

49

AFAIK phương pháp trì hoãn chỉ hoạt động đối với sửa đổi CSS số.

Đối với các mục đích khác, JavaScript đi kèm với phương thức setTimeout:

window.setTimeout(function(){$("#div").removeClass("error");}, 1000);

11
+1: Đừng sử dụng Jquery vì lợi ích của Jquery. Có những giải pháp javascript đơn giản cho nhiều vấn đề.
Joel

1
+1: Giống như bình luận đầu tiên. Đơn giản JS cũng hoạt động tốt một số lần.
wowpatrick

1
+1 vì đơn giản, nhưng cũng có + 1 câu trả lời được chấp nhận - vì nó chỉ ra cho tôi rằng .queue () thực sự vượt qua đối tượng tiếp tục phải được gọi thủ công ('next ()'). Tôi đã dành nửa giờ để tự hỏi tại sao chuỗi cuộc gọi lại không tham số của tôi chỉ thực hiện cuộc gọi đầu tiên - nhiều ví dụ trên các trang web khác sử dụng một độ trễ duy nhất trong chuỗi và cuộc gọi lại không tham số, đó là một sự hiểu sai quá mức của cơ chế đó
quetzalcoatl

1
Chỉ cần một lưu ý dành cho người đi bộ: setTimeout đến từ đối tượng cửa sổ của trình duyệt (BOM). JavaScript (được hiểu là ECMA Script) không có phương thức đó.
corbacho

9

Tôi biết đây là một bài viết rất cũ nhưng tôi đã kết hợp một vài câu trả lời vào một hàm bao bọc jQuery hỗ trợ chuỗi. Hy vọng nó mang lại lợi ích cho ai đó:

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

Và đây là một trình bao bọc removeClass:

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

Bây giờ bạn có thể làm những thứ như thế này - đợi 1 giây, thêm .error, đợi 3 giây , xóa .error:

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


Rất hữu ích! Cảm ơn bạn!
Fabian Jäger

6

Thao tác CSS của jQuery không được xếp hàng, nhưng bạn có thể thực hiện nó bên trong hàng đợi 'fx' bằng cách thực hiện:

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

Khá giống với cách gọi setTimeout nhưng thay vào đó sử dụng mecanism hàng đợi của jQuery.


Điều này làm việc cho tôi tốt hơn sau đó chấp nhận câu trả lời (các cuộc gọi không lặp lại nếu có một chuyển đổi chuyển tiếp trong lớp).
vatavale

4

Tất nhiên sẽ đơn giản hơn nếu bạn mở rộng jQuery như thế này:

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

sau đó bạn có thể sử dụng chức năng này như addClass:

$('div').addClassDelay('clicked',1000);

1
và nếu bạn muốn thêm hỗ trợ chuỗi, hãy đọc những điều cơ bản về tạo plugin hoặc chỉ cần thêm return thisvào chức năng ...
user6322596

2

Độ trễ hoạt động trên một hàng đợi. và theo như tôi biết thì thao tác css (khác với thông qua hoạt hình) không được xếp hàng.


2

delaykhông hoạt động trên không có chức năng xếp hàng, vì vậy chúng ta nên sử dụng setTimeout().

Và bạn không cần phải phân tách mọi thứ. Tất cả bạn cần làm là bao gồm mọi thứ trong một setTimeOutphương thức:

setTimeout(function () {
    $("#div").addClass("error").delay(1000).removeClass("error");
}, 1000);

Bạn không phải sử dụng delay () với setTimeout ().
MattYao

@MattYao Tôi không nghĩ bạn có ý tưởng. Nếu bạn không sử dụng setTimeout, thì sự chậm trễ đó sẽ không hoạt động
Alex Jolig

1
Giải pháp không cần cả hai để làm việc cùng nhau. Sử dụng delay () với queue () trong jQuery hoặc đơn giản là sử dụng setTimeout () có thể giải quyết vấn đề. Tôi không nói câu trả lời của bạn là sai.
MattYao

0

Thử cái này:

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

0

Hãy thử funtion mũi tên đơn giản này:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.