如果使用jQuery添加或更改CSS类,如何触发事件? CSS类的变化是否会触发jQuery change()事件?
当前回答
依我看,更好的解决方案是结合@RamboNo5和@Jason的两个答案
我的意思是重写addClass函数并添加一个名为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
});
});
其他回答
您可以绑定domsubtremodified事件。我在这里加一个例子:
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');
});
});
http://jsfiddle.net/hnCxK/13/
如果你需要触发一个特定的事件,你可以重写addClass()方法来触发一个名为'classadded'的自定义事件。
这里有:
(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
// ...
});
只是一个概念的证明:
查看要点,查看一些注释,并保持更新:
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));
用法很简单,只要在你想观察和操作类的节点上添加一个新的监听器:
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');
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');
});
如果您想检测类更改,最好的方法是使用Mutation observer,它可以让您完全控制任何属性更改。但是,您需要自己定义监听器,并将其附加到您正在监听的元素。好消息是,一旦追加了listener,您就不需要手动触发任何事情。
$(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
}
});
});
在本例中,事件监听器被附加到每个元素,但在大多数情况下您不希望这样(节省内存)。将这个“attrchange”监听器附加到你想观察的元素上。