menjiwai addClass / removeClass dengan jQuery

226

Saya menggunakan jQuery dan jQuery-ui dan ingin menghidupkan berbagai atribut pada berbagai objek.

Demi menjelaskan masalah ini di sini saya telah menyederhanakannya menjadi satu div yang berubah dari biru menjadi merah ketika pengguna mengatasinya.

Saya bisa mendapatkan perilaku yang saya inginkan saat menggunakan animate(), namun ketika melakukannya, style yang saya animasikan harus ada dalam kode animasi dan terpisah dari style sheet saya. (lihat contoh 1 )

Alternatif menggunakan addClass()dan removeClass()tetapi saya belum dapat membuat kembali perilaku tepat yang bisa saya dapatkan animate(). (lihat contoh 2 )


Contoh 1

Mari kita lihat kode yang saya miliki dengan animate():

$('#someDiv')
  .mouseover(function(){
    $(this).stop().animate( {backgroundColor:'blue'}, {duration:500});
  })
  .mouseout(function(){
    $(this).stop().animate( {backgroundColor:'red'}, {duration:500});
  });

ini menampilkan semua perilaku yang saya cari:

  1. Animasi dengan lancar antara merah dan biru.
  2. Tidak ada animasi 'overqueue-ing' ketika pengguna menggerakkan mouse mereka dengan cepat masuk dan keluar dari div.
  3. Jika pengguna menggerakkan mouse mereka keluar / masuk saat animasi masih diputar dengan mudah antara negara 'setengah' saat ini dan negara 'tujuan' baru.

Tapi karena perubahan style didefinisikan di animate()saya harus mengubah nilai style di sana, dan tidak bisa hanya mengarahkannya ke stylesheet saya. 'Pemisahan' ini tentang di mana gaya didefinisikan adalah sesuatu yang benar-benar menggangguku.


Contoh 2

Ini adalah upaya terbaik saya saat ini untuk menggunakan addClass()dan removeClass(perhatikan bahwa agar animasi berfungsi, Anda memerlukan jQuery-ui):

//assume classes 'red' and 'blue' are defined

$('#someDiv')
  .addClass('blue')
  .mouseover(function(){
    $(this).stop(true,false).removeAttr('style').addClass('red', {duration:500});
  })
  .mouseout(function(){
    $(this).stop(true,false).removeAttr('style').removeClass('red', {duration:500});
  });

Ini menunjukkan properti 1. dan 2. dari persyaratan awal saya, namun 3 tidak berfungsi.

Saya mengerti alasannya:

Saat menjiwai addClass()dan removeClass()jQuery menambahkan gaya sementara ke elemen, dan kemudian menambahkan nilai yang sesuai sampai mereka mencapai nilai-nilai kelas yang disediakan, dan hanya kemudian benar-benar menambah / menghapus kelas.

Karena itu saya harus menghapus atribut style, jika tidak, jika animasi dihentikan setengah jalan, atribut style akan tetap ada dan secara permanen akan menimpa nilai kelas apa pun, karena atribut style dalam tag memiliki kepentingan yang lebih tinggi daripada gaya kelas.

Namun ketika animasi setengah selesai belum menambahkan kelas baru, dan dengan solusi ini warna melompat ke warna sebelumnya ketika pengguna menggerakkan mouse mereka sebelum animasi selesai.


Yang saya inginkan idealnya adalah dapat melakukan sesuatu seperti ini:

$('#someDiv')
  .mouseover(function(){
    $(this).stop().animate( getClassContent('blue'), {duration:500});
  })
  .mouseout(function(){
    $(this).stop().animate( getClassContent('red'), {duration:500});
  });

Di mana getClassContenthanya akan mengembalikan isi kelas yang disediakan. Poin kuncinya adalah bahwa dengan cara ini saya tidak harus menyimpan definisi gaya saya di semua tempat, tetapi dapat menyimpannya di kelas di stylesheet saya.

Johannes
sumber
1
Versi IE apa yang perlu Anda dukung? Apakah Anda senang dengan IE9? Atau apakah Anda perlu mendukung lebih rendah?
tw16
1
Saya tidak peduli tentang IE sama sekali jujur. Ini semua telah diuji dengan browser webkit saja (safari / chrome).
Johannes
bagaimana getClassContentkelihatannya?
sreginogemoh

Jawaban:

311

Karena Anda tidak khawatir tentang IE, mengapa tidak menggunakan transisi css untuk menyediakan animasi dan jQuery untuk mengubah kelas. Contoh langsung: http://jsfiddle.net/tw16/JfK6N/

#someDiv{
    -webkit-transition: all 0.5s ease;
    -moz-transition: all 0.5s ease;
    -o-transition: all 0.5s ease;
    transition: all 0.5s ease;
}
tw16
sumber
14
Pada 2015-06-12 ini didukung di - IE 10+ - Chrome 26+ - FireFox 16+ - Safari 6.1+ - Opera 12.1+ -webkit, -moz, -o hanya diperlukan untuk peramban yang lebih lama. Anda mungkin dapat meninggalkannya untuk menghemat ruang.
clst
3
@clst, saya lebih suka kompatibilitas ke belakang dengan browser lama daripada menghemat beberapa byte ruang.
Arman H
96

Solusi lain (tetapi membutuhkan jQueryUI seperti yang ditunjukkan oleh Richard Neil Ilagan dalam komentar): -

addClass, removeClass dan toggleClass juga menerima argumen kedua; durasi waktu untuk berpindah dari satu kondisi ke kondisi lainnya.

$(this).addClass('abc',1000);

Lihat jsfiddle: - http://jsfiddle.net/6hvZT/1/

Omar Tariq
sumber
28
Perhatikan bahwa ini memerlukan jQuery UI. jQuery di luar kotak tidak mendukung animasi tweening untuk xxxClass()fungsi.
Richard Neil Ilagan
@ Richard Neil Ilagan: Terima kasih telah memberi tahu. Saya sangat merindukan hal itu.
Omar Tariq
4
Bisakah Anda menunjukkan file apa yang harus diunduh dan disertakan dalam file .html sehingga saya bisa menggunakan jQueryUI hanya untuk xxxClassanimasi yang tweening dengan cara ini?
sodiumnitrate
[jqueryui.com] (jqueryui.com) @sodiumnitrate
joe_young
1
Solusi ini juga tidak menganimasikan cara yang sama seperti slide () atau animate (). Nilai milidetik adalah penundaan, yang bukan merupakan animasi.
Solona Armstrong
38

Anda bisa menggunakan jquery ui's switchClass, Heres contoh:

$( "selector" ).switchClass( "oldClass", "newClass", 1000, "easeInOutQuad" );

Atau lihat jsfiddle ini .

by0
sumber
1
-1. Anda tidak memenuhi batasan 1, 2 dan 3 yang saya cantumkan di pos asli. SwitchClass secara khusus menangani persyaratan 2 dan 3 dengan buruk.
Johannes
12

Anda hanya perlu jQuery UI effects-core (13KB), untuk mengaktifkan durasi penambahan (seperti yang ditunjukkan Omar Tariq)

Patrick
sumber
5

Saya melihat ini tetapi ingin memiliki tingkat transisi yang berbeda untuk masuk dan keluar.

Inilah yang akhirnya saya lakukan:

//css
.addedClass {
    background: #5eb4fc;
}

// js
function setParentTransition(id, prop, delay, style, callback) {
    $(id).css({'-webkit-transition' : prop + ' ' + delay + ' ' + style});
    $(id).css({'-moz-transition' : prop + ' ' + delay + ' ' + style});
    $(id).css({'-o-transition' : prop + ' ' + delay + ' ' + style});
    $(id).css({'transition' : prop + ' ' + delay + ' ' + style});
    callback();
}
setParentTransition(id, 'background', '0s', 'ease', function() {
    $('#elementID').addClass('addedClass');
});

setTimeout(function() {
    setParentTransition(id, 'background', '2s', 'ease', function() {
        $('#elementID').removeClass('addedClass');
    });
});

Ini secara instan mengubah warna latar belakang ke # 5eb4fc dan kemudian perlahan-lahan kembali normal selama 2 detik.

Ini biola

Tj Gienger
sumber
2

Meskipun, pertanyaannya cukup lama, saya menambahkan info yang tidak ada dalam jawaban lain.

OP menggunakan stop () untuk menghentikan animasi saat ini segera setelah acara selesai. Namun, menggunakan campuran parameter yang tepat dengan fungsi akan membantu. misalnya. stop (true, true) atau stop (true, false) karena ini memengaruhi animasi yang antri dengan baik.

Tautan berikut menggambarkan demo yang menunjukkan berbagai parameter yang tersedia dengan stop () dan perbedaannya dari selesai ().

http://api.jquery.com/finish/

Meskipun OP tidak memiliki masalah menggunakan JqueryUI, ini untuk pengguna lain yang mungkin menemukan skenario serupa tetapi tidak dapat menggunakan JqueryUI / perlu untuk mendukung IE7 dan 8 juga.

Anurag
sumber