Saya ingin mendapatkan sesuatu seperti:
$('#myDiv').bind('class "submission ok" added'){
alert('class "submission ok" has been added');
});
Jawaban:
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');
});
// in another js file, far, far away
$('#myDiv').on('classChange', function() {
// do stuff
});
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 penggunaan bind()
. Saya tidak yakin bagaimana itu 'menyelesaikan' apa pun
MutationObserver
berfungsi untuk saya
Anda 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 */ }
});
$(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-delegation
Gunakan trigger
untuk mengaktifkan acara Anda sendiri. Kapanpun Anda mengubah kelas, tambahkan pemicu dengan nama
$("#main").on('click', function () {
$("#chld").addClass("bgcolorRed").trigger("cssFontSet");
});
$('#chld').on('cssFontSet', function () {
alert("Red bg set ");
});
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