jQuery: Dapatkah saya memanggil delay () antara addClass () dan semacamnya?

178

Sesuatu yang sederhana seperti:

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

sepertinya tidak berfungsi. Apa yang akan menjadi alternatif termudah?

serg
sumber
10
ingin melakukan hal yang persis sama. Akan lebih keren untuk menelepon$("#div").addClassTemporarily("error",1000)
Sebastien Lorber

Jawaban:

365

Anda dapat membuat item antrian baru untuk menghapus kelas:

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

Atau menggunakan metode dequeue :

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

Alasan Anda perlu menelepon nextatau dequeuememberi tahu jQuery bahwa Anda telah selesai dengan item yang antri ini dan harus pindah ke item berikutnya.

PetersenDidIt
sumber
3
Saya suka opsi ini karena membuatnya mudah untuk memberikan referensi ke objek jquery yang digunakan dalam fungsi antrian, sehingga dapat digunakan dalam konteks yang lebih umum (tanpa nama kode yang keras).
GrandmasterB
5
Mengapa kita perlu "selanjutnya"? Bisakah kita melakukan $ ("# div"). AddClass ("error"). Delay (1000) .queue (function () {$ (this) .removeClass ("error");}); Tampak lebih elegan?
Vennsoh
@Vennsoh Anda tidak perlu melewati item antrian 'berikutnya'. Anda dapat memilih untuk menggunakan metode dequeue (): api.jquery.com/dequeue
gfullam
49

AFAIK metode penundaan hanya berfungsi untuk modifikasi CSS numerik.

Untuk keperluan lain, JavaScript hadir dengan metode setTimeout:

window.setTimeout(function(){$("#div").removeClass("error");}, 1000);
Jasper
sumber
11
+1: Jangan gunakan Jquery demi Jquery. Ada solusi javascript sederhana untuk banyak masalah.
Joel
1
+1: Sama seperti komentar pertama. JS sederhana juga berfungsi dengan baik beberapa kali.
wowpatrick
1
Memberi +1 untuk kesederhanaan, tetapi juga memberi +1 pada jawaban yang diterima - seperti yang saya tunjukkan bahwa .queue () benar-benar melewati objek lanjutan yang harus dipanggil secara manual ('berikutnya ()'). Saya telah menghabiskan setengah jam bertanya-tanya mengapa rantai panggilan balik tanpa parameter saya hanya mengeksekusi yang pertama - banyak contoh di situs lain menggunakan penundaan tunggal dalam rantai dan panggilan balik tanpa parameter, yang sedikit menyesatkan terlalu banyak penyederhanaan mekanisme itu
quetzalcoatl
1
Hanya catatan pedant: setTimeout berasal dari objek jendela browser (BOM). JavaScript (dipahami sebagai ECMA Script) tidak memiliki metode itu.
corbacho
9

Saya tahu ini posting yang sangat lama tetapi saya telah menggabungkan beberapa jawaban ke dalam fungsi pembungkus jQuery yang mendukung perangkaian. Semoga bermanfaat bagi seseorang:

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

Dan inilah pembungkus removeClass:

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

Sekarang Anda dapat melakukan hal-hal seperti ini - tunggu 1dtk, tambahkan .error, tunggu 3dtk, hapus .error:

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

Bak pasir
sumber
Sangat membantu! Terima kasih!
Fabian Jäger
6

Manipulasi CSS jQuery tidak di-antri, tetapi Anda dapat membuatnya dieksekusi di dalam antrian 'fx' dengan melakukan:

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

Hal yang sama seperti memanggil setTimeout tetapi menggunakan mekanisme antrian jQuery sebagai gantinya.

warpdesign
sumber
Ini bekerja untuk saya lebih baik daripada jawaban yang diterima (panggilan tidak berulang jika ada transformasi transisi di kelas).
vatavale
4

Tentu saja akan lebih sederhana jika Anda memperpanjang jQuery seperti ini:

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

setelah itu Anda bisa menggunakan fungsi ini seperti addClass:

$('div').addClassDelay('clicked',1000);
pengguna6322596
sumber
1
dan jika Anda ingin menambahkan dukungan rangkaian, baca dasar-dasar te tentang pembuatan plugin, atau cukup tambahkan return thiske fungsi ...
user6322596
2

Keterlambatan beroperasi dalam antrian. dan sejauh yang saya tahu manipulasi css (selain melalui bernyawa) tidak mengantri.

prodigitalson
sumber
2

delaytidak berfungsi pada fungsi tidak ada antrian, jadi kita harus menggunakan setTimeout().

Dan Anda tidak perlu memisahkan hal-hal. Yang perlu Anda lakukan adalah memasukkan semuanya dalam suatu setTimeOutmetode:

setTimeout(function () {
    $("#div").addClass("error").delay(1000).removeClass("error");
}, 1000);
Alex Jolig
sumber
Anda tidak harus menggunakan delay () dengan setTimeout ().
MattYao
@MattYao Saya tidak berpikir Anda mendapatkan idenya. Jika Anda tidak menggunakan setTimeout, maka penundaan itu tidak akan berhasil
Alex Jolig
1
Solusinya tidak perlu keduanya untuk bekerja sama. Baik menggunakan delay () dengan antrian () di jQuery atau cukup menggunakan setTimeout () dapat menyelesaikan masalah. Saya tidak mengatakan jawaban Anda salah.
MattYao
0

Coba ini:

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

Coba funtion panah sederhana ini:

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

csandreas1
sumber