Bagaimana saya bisa menjalankan suatu acara jika kelas CSS ditambahkan atau diubah menggunakan jQuery? Apakah perubahan kelas CSS memicu change()
acara jQuery ?
Bagaimana saya bisa menjalankan suatu acara jika kelas CSS ditambahkan atau diubah menggunakan jQuery? Apakah perubahan kelas CSS memicu change()
acara jQuery ?
Jawaban:
Setiap kali Anda mengubah kelas dalam skrip Anda, Anda bisa menggunakan a trigger
untuk meningkatkan acara Anda sendiri.
$(this).addClass('someClass');
$(mySelector).trigger('cssClassChanged')
....
$(otherSelector).bind('cssClassChanged', data, function(){ do stuff });
tetapi sebaliknya, tidak, tidak ada cara untuk memecat suatu peristiwa ketika kelas berubah. change()
hanya menyala setelah fokus meninggalkan input yang inputnya telah diubah.
$(function() {
var button = $('.clickme')
, box = $('.box')
;
button.on('click', function() {
box.removeClass('box');
$(document).trigger('buttonClick');
});
$(document).on('buttonClick', function() {
box.text('Clicked!');
});
});
.box { background-color: red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">Hi</div>
<button class="clickme">Click me</button>
changeColor
acara tersebut, dan semua objek yang berlangganan acara itu dapat bereaksi sesuai.
IMHO solusi yang lebih baik adalah menggabungkan dua jawaban oleh @ RamboNo5 dan @Jason
Maksud saya mengesampingkan fungsi addClass dan menambahkan acara kustom yang disebut cssClassChanged
// Create a closure
(function(){
// Your base, I'm in it!
var originalAddClassMethod = jQuery.fn.addClass;
jQuery.fn.addClass = function(){
// Execute the original method.
var result = originalAddClassMethod.apply( this, arguments );
// trigger a custom event
jQuery(this).trigger('cssClassChanged');
// return the original result
return result;
}
})();
// document ready function
$(function(){
$("#YourExampleElementID").bind('cssClassChanged', function(){
//do stuff here
});
});
$()
, ketika tindakan nyata dimulai.
cssClassChanged
acara ini ke suatu elemen, Anda harus menyadari bahwa itu akan dipecat bahkan ketika anaknya mengubah kelas mereka. Karenanya, jika misalnya Anda tidak ingin memecat acara ini untuk mereka, tambahkan saja sesuatu seperti $("#YourExampleElementID *").on('cssClassChanged', function(e) { e.stopPropagation(); });
setelah bind Anda. Bagaimanapun, solusi yang sangat bagus, terima kasih!
Jika Anda ingin mendeteksi perubahan kelas, cara terbaik adalah menggunakan Pengamat Mutasi, yang memberi Anda kontrol penuh atas perubahan atribut apa pun. Namun Anda harus mendefinisikan pendengar sendiri, dan menambahkannya ke elemen yang Anda dengarkan. Untung Anda tidak perlu memicu apa pun secara manual setelah pendengar ditambahkan.
$(function() {
(function($) {
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
$.fn.attrchange = function(callback) {
if (MutationObserver) {
var options = {
subtree: false,
attributes: true
};
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(e) {
callback.call(e.target, e.attributeName);
});
});
return this.each(function() {
observer.observe(this, options);
});
}
}
})(jQuery);
//Now you need to append event listener
$('body *').attrchange(function(attrName) {
if(attrName=='class'){
alert('class changed');
}else if(attrName=='id'){
alert('id changed');
}else{
//OTHER ATTR CHANGED
}
});
});
Dalam contoh ini pendengar acara ditambahkan ke setiap elemen, tetapi Anda tidak ingin itu dalam kebanyakan kasus (menghemat memori). Tambahkan pendengar "attrchange" ini ke elemen yang ingin Anda amati.
DOMMutationObserver
.
Saya sarankan Anda mengganti fungsi addClass. Anda bisa melakukannya dengan cara ini:
// Create a closure
(function(){
// Your base, I'm in it!
var originalAddClassMethod = jQuery.fn.addClass;
jQuery.fn.addClass = function(){
// Execute the original method.
var result = originalAddClassMethod.apply( this, arguments );
// call your function
// this gets called everytime you use the addClass method
myfunction();
// return the original result
return result;
}
})();
// document ready function
$(function(){
// do stuff
});
Hanya bukti konsep:
Lihatlah intinya untuk melihat beberapa anotasi dan tetap terbarui:
https://gist.github.com/yckart/c893d7db0f49b1ea4dfb
(function ($) {
var methods = ['addClass', 'toggleClass', 'removeClass'];
$.each(methods, function (index, method) {
var originalMethod = $.fn[method];
$.fn[method] = function () {
var oldClass = this[0].className;
var result = originalMethod.apply(this, arguments);
var newClass = this[0].className;
this.trigger(method, [oldClass, newClass]);
return result;
};
});
}(window.jQuery || window.Zepto));
Penggunaannya cukup sederhana, cukup tambahkan listender baru pada node yang ingin Anda amati dan memanipulasi kelas seperti biasanya:
var $node = $('div')
// listen to class-manipulation
.on('addClass toggleClass removeClass', function (e, oldClass, newClass) {
console.log('Changed from %s to %s due %s', oldClass, newClass, e.type);
})
// make some changes
.addClass('foo')
.removeClass('foo')
.toggleClass('foo');
this[0]
tidak terdefinisi ... cukup ganti ujung baris dengan var oldClass
dan var newClass
dengan tugas berikut:= (this[0] ? this[0].className : "");
menggunakan mutasi jquery terbaru
var $target = jQuery(".required-entry");
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.attributeName === "class") {
var attributeValue = jQuery(mutation.target).prop(mutation.attributeName);
if (attributeValue.indexOf("search-class") >= 0){
// do what you want
}
}
});
});
observer.observe($target[0], {
attributes: true
});
// kode apa pun yang memperbarui div yang memiliki entri wajib kelas yang dalam $ target seperti $ target.addClass ('kelas pencarian');
change()
tidak menyala ketika kelas CSS ditambahkan atau dihapus atau definisi berubah. Ini menyala dalam keadaan seperti ketika nilai kotak pilih dipilih atau tidak dipilih.
Saya tidak yakin apakah maksud Anda jika definisi kelas CSS diubah (yang dapat dilakukan secara terprogram tetapi membosankan dan umumnya tidak disarankan) atau jika kelas ditambahkan atau dihapus ke suatu elemen. Tidak ada cara untuk menangkap kejadian ini dengan andal dalam kedua kasus tersebut.
Anda tentu saja dapat membuat acara Anda sendiri untuk ini, tetapi ini hanya dapat digambarkan sebagai penasehat . Itu tidak akan menangkap kode yang bukan milikmu melakukannya.
Atau Anda bisa mengganti / mengganti metode addClass()
(dll) di jQuery tetapi ini tidak akan menangkap ketika dilakukan melalui vanilla Javascript (walaupun saya kira Anda juga bisa mengganti metode itu).
Ada satu cara lagi tanpa memicu acara khusus
Plug-in jQuery untuk memantau Perubahan Elemen CSS Html oleh Rick Strahl
Mengutip dari atas
Plug-in jam tangan berfungsi dengan menghubungkan ke DOMAttrModified di FireFox, ke onPropertyChanged di Internet Explorer, atau dengan menggunakan timer dengan setInterval untuk menangani deteksi perubahan untuk browser lain. Sayangnya WebKit tidak mendukung DOMAttrModified secara konsisten saat ini sehingga Safari dan Chrome saat ini harus menggunakan mekanisme setInterval yang lebih lambat.
Pertanyaan bagus. Saya menggunakan Menu Dropdown Bootstrap, dan diperlukan untuk menjalankan suatu peristiwa ketika Bootstrap Dropdown disembunyikan. Ketika dropdown dibuka, div yang berisi dengan nama kelas "tombol-grup" menambahkan kelas "terbuka"; dan tombol itu sendiri memiliki atribut "aria-extended" yang disetel ke true. Ketika dropdown ditutup, kelas "terbuka" itu dihapus dari div yang mengandung, dan aria-diperluas beralih dari true ke false.
Itu mengarahkan saya ke pertanyaan ini, tentang bagaimana mendeteksi perubahan kelas.
Dengan Bootstrap, ada "Acara Dropdown" yang dapat dideteksi. Cari "Acara Dropdown" di tautan ini. http://www.w3schools.com/bootstrap/bootstrap_ref_js_dropdown.asp
Berikut adalah contoh cepat-dan-kotor dari menggunakan acara ini pada Bootstrap Dropdown.
$(document).on('hidden.bs.dropdown', function(event) {
console.log('closed');
});
Sekarang saya menyadari ini lebih spesifik daripada pertanyaan umum yang diajukan. Tapi saya membayangkan pengembang lain yang mencoba mendeteksi acara terbuka atau tertutup dengan Bootstrap Dropdown akan menemukan ini membantu. Seperti saya, mereka mungkin pada awalnya hanya mencoba mendeteksi perubahan kelas elemen (yang tampaknya tidak begitu sederhana). Terima kasih.
Jika Anda perlu memicu suatu peristiwa tertentu, Anda dapat mengganti metode addClass () untuk memecat acara khusus yang disebut 'classadded'.
Di sini caranya:
(function() {
var ev = new $.Event('classadded'),
orig = $.fn.addClass;
$.fn.addClass = function() {
$(this).trigger(ev, arguments);
return orig.apply(this, arguments);
}
})();
$('#myElement').on('classadded', function(ev, newClasses) {
console.log(newClasses + ' added!');
console.log(this);
// Do stuff
// ...
});
Anda dapat mengikat acara DOMSubtreeModified. Saya menambahkan contoh di sini:
HTML
<div id="mutable" style="width:50px;height:50px;">sjdfhksfh<div>
<div>
<button id="changeClass">Change Class</button>
</div>
JavaScript
$(document).ready(function() {
$('#changeClass').click(function() {
$('#mutable').addClass("red");
});
$('#mutable').bind('DOMSubtreeModified', function(e) {
alert('class changed');
});
});
jika Anda tahu acara apa yang mengubah kelas di tempat pertama Anda dapat menggunakan sedikit keterlambatan pada acara yang sama dan memeriksa kelas. contoh
//this is not the code you control
$('input').on('blur', function(){
$(this).addClass('error');
$(this).before("<div class='someClass'>Warning Error</div>");
});
//this is your code
$('input').on('blur', function(){
var el= $(this);
setTimeout(function(){
if ($(el).hasClass('error')){
$(el).removeClass('error');
$(el).prev('.someClass').hide();
}
},1000);
});
var timeout_check_change_class;
function check_change_class( selector )
{
$(selector).each(function(index, el) {
var data_old_class = $(el).attr('data-old-class');
if (typeof data_old_class !== typeof undefined && data_old_class !== false)
{
if( data_old_class != $(el).attr('class') )
{
$(el).trigger('change_class');
}
}
$(el).attr('data-old-class', $(el).attr('class') );
});
clearTimeout( timeout_check_change_class );
timeout_check_change_class = setTimeout(check_change_class, 10, selector);
}
check_change_class( '.breakpoint' );
$('.breakpoint').on('change_class', function(event) {
console.log('haschange');
});