Tidak ada acara yang dimunculkan saat kelas berubah. Alternatifnya adalah dengan memunculkan acara secara manual saat Anda mengubah kelas secara terprogram:
$someElement.on('event', function() {
$('#myDiv').addClass('submission-ok').trigger('classChange');
});
$('#myDiv').on('classChange', function() {
});
MEMPERBARUI
Pertanyaan ini sepertinya mengumpulkan beberapa pengunjung, jadi berikut adalah pembaruan dengan pendekatan yang dapat digunakan tanpa harus mengubah kode yang sudah ada menggunakan yang baru MutationObserver
:
var $div = $("#foo");
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.attributeName === "class") {
var attributeValue = $(mutation.target).prop(mutation.attributeName);
console.log("Class attribute changed to:", attributeValue);
}
});
});
observer.observe($div[0], {
attributes: true
});
$div.addClass('red');
.red { color: #C00; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo" class="bar">#foo.bar</div>
Ketahuilah bahwa MutationObserver
ini hanya tersedia untuk browser yang lebih baru, khususnya Chrome 26, FF 14, IE 11, Opera 15 dan Safari 6. Lihat MDN untuk lebih jelasnya. Jika Anda perlu mendukung browser lama, maka Anda perlu menggunakan metode yang saya uraikan di contoh pertama saya.
trigger()
) meskipun perhatikan bahwa itu sangat ketinggalan jaman karena penggunaanbind()
. Saya tidak yakin bagaimana itu 'menyelesaikan' apa punMutationObserver
berfungsi untuk sayaAnda dapat mengganti fungsi addClass dan removeClass jQuery asli dengan fungsi Anda sendiri yang akan memanggil fungsi asli dan kemudian memicu peristiwa khusus. (Menggunakan fungsi anonim yang memanggil sendiri untuk memuat referensi fungsi asli)
(function( func ) { $.fn.addClass = function() { // replace the existing function on $.fn func.apply( this, arguments ); // invoke the original function this.trigger('classChanged'); // trigger the custom event return this; // retain jQuery chainability } })($.fn.addClass); // pass the original function as an argument (function( func ) { $.fn.removeClass = function() { func.apply( this, arguments ); this.trigger('classChanged'); return this; } })($.fn.removeClass);
Maka sisa kode Anda akan menjadi sesederhana yang Anda harapkan.
$(selector).on('classChanged', function(){ /*...*/ });
Memperbarui:
Pendekatan ini membuat asumsi bahwa kelas hanya akan diubah melalui metode addClass dan removeClass jQuery. Jika kelas dimodifikasi dengan cara lain (seperti manipulasi langsung atribut kelas melalui elemen DOM) penggunaan sesuatu seperti
MutationObserver
s seperti yang dijelaskan dalam jawaban yang diterima di sini akan diperlukan.Juga sebagai perbaikan pasangan untuk metode ini:
classAdded
) atau dihapus (classRemoved
) dengan kelas tertentu yang diteruskan sebagai argumen ke fungsi panggilan balik dan hanya dipicu jika kelas tertentu benar-benar ditambahkan (tidak ada sebelumnya) atau dihapus (sudah ada sebelumnya)Hanya terpicu
classChanged
jika ada kelas yang benar-benar diubah(function( func ) { $.fn.addClass = function(n) { // replace the existing function on $.fn this.each(function(i) { // for each element in the collection var $this = $(this); // 'this' is DOM element in this context var prevClasses = this.getAttribute('class'); // note its original classes var classNames = $.isFunction(n) ? n(i, prevClasses) : n.toString(); // retain function-type argument support $.each(classNames.split(/\s+/), function(index, className) { // allow for multiple classes being added if( !$this.hasClass(className) ) { // only when the class is not already present func.call( $this, className ); // invoke the original function to add the class $this.trigger('classAdded', className); // trigger a classAdded event } }); prevClasses != this.getAttribute('class') && $this.trigger('classChanged'); // trigger the classChanged event }); return this; // retain jQuery chainability } })($.fn.addClass); // pass the original function as an argument (function( func ) { $.fn.removeClass = function(n) { this.each(function(i) { var $this = $(this); var prevClasses = this.getAttribute('class'); var classNames = $.isFunction(n) ? n(i, prevClasses) : n.toString(); $.each(classNames.split(/\s+/), function(index, className) { if( $this.hasClass(className) ) { func.call( $this, className ); $this.trigger('classRemoved', className); } }); prevClasses != this.getAttribute('class') && $this.trigger('classChanged'); }); return this; } })($.fn.removeClass);
Dengan fungsi pengganti ini, Anda kemudian dapat menangani setiap kelas yang diubah melalui classChanged atau kelas tertentu yang ditambahkan atau dihapus dengan memeriksa argumen ke fungsi callback:
$(document).on('classAdded', '#myElement', function(event, className) { if(className == "something") { /* do something */ } });
sumber
$(parent_selector).on('classChanged', target_selector, function(){ /*...*/ });
. Butuh beberapa saat bagi saya untuk melihat mengapa elemen yang saya buat secara dinamis tidak mengaktifkan penangan. Lihat learn.jquery.com/events/event-delegationGunakan
trigger
untuk mengaktifkan acara Anda sendiri. Kapanpun Anda mengubah kelas, tambahkan pemicu dengan namaJS Fiddle DEMO
$("#main").on('click', function () { $("#chld").addClass("bgcolorRed").trigger("cssFontSet"); }); $('#chld').on('cssFontSet', function () { alert("Red bg set "); });
Pelajari jQuery: Blog tutorial jQuery sederhana dan mudah
sumber
Anda dapat menggunakan sesuatu seperti ini:
$(this).addClass('someClass'); $(Selector).trigger('ClassChanged') $(otherSelector).bind('ClassChanged', data, function(){//stuff });
tetapi sebaliknya, tidak, tidak ada fungsi yang telah ditentukan untuk mengaktifkan peristiwa saat kelas berubah.
Baca lebih lanjut tentang pemicu di sini
sumber