如果使用 jQuery 添加或更改 CSS 类,我如何触发事件?更改 CSS 类会触发 jQuerychange()
事件吗?
13 回答
每当您更改脚本中的类时,您都可以使用 atrigger
来引发您自己的事件。
$(this).addClass('someClass');
$(mySelector).trigger('cssClassChanged')
....
$(otherSelector).bind('cssClassChanged', data, function(){ do stuff });
但除此之外,不,当类发生变化时,没有固定的方法来触发事件。change()
仅在焦点离开输入已更改的输入后触发。
$(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>
恕我直言,更好的解决方案是将@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
});
});
如果你想检测类变化,最好的方法是使用 Mutation Observers,它可以让你完全控制任何属性变化。但是,您需要自己定义侦听器,并将其附加到您正在侦听的元素中。好消息是,一旦附加了侦听器,您就不需要手动触发任何东西。
$(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”侦听器附加到您要观察的元素。
我建议你重写 addClass 函数。你可以这样做:
// 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
});
只是一个概念证明:
查看要点以查看一些注释并保持最新:
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');
使用最新的 jquery 突变
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
});
// 任何更新具有类required-entry 的div 的代码,该类位于 $target 中,例如 $target.addClass('search-class');
change()
添加或删除 CSS 类或定义更改时不会触发。它在选择框值被选中或取消选中等情况下触发。
我不确定您的意思是是否更改了 CSS 类定义(可以通过编程方式完成,但很乏味且通常不推荐),或者是否向元素添加或删除了类。无论哪种情况,都无法可靠地捕捉到这种情况。
您当然可以为此创建自己的事件,但这只能被描述为建议性的。它不会捕获不属于您的代码。
或者,您可以覆盖/替换addClass()
jQuery 中的(等)方法,但这不会在通过 vanilla Javascript 完成时捕获(尽管我猜您也可以替换这些方法)。
还有一种不触发自定义事件的方法
用于监控 Html 元素 CSS 更改的 jQuery 插件 Rick Strahl
从上面引用
watch 插件通过连接到 FireFox 中的 DOMAttrModified、连接到 Internet Explorer 中的 onPropertyChanged 或使用带有 setInterval 的计时器来处理检测其他浏览器的更改来工作。不幸的是,WebKit 目前并不始终支持 DOMAttrModified,因此 Safari 和 Chrome 目前不得不使用较慢的 setInterval 机制。
好问题。我正在使用 Bootstrap 下拉菜单,并且需要在 Bootstrap 下拉菜单被隐藏时执行一个事件。当下拉菜单打开时,包含类名为“button-group”的div添加了一个类“open”;并且按钮本身的“aria-expanded”属性设置为true。当下拉菜单关闭时,“open”类将从包含的 div 中删除,并且 aria-expanded 从 true 切换为 false。
这让我想到了这个问题,即如何检测班级变化。
使用 Bootstrap,可以检测到“下拉事件”。在此链接中查找“下拉事件”。 http://www.w3schools.com/bootstrap/bootstrap_ref_js_dropdown.asp
这是在 Bootstrap Dropdown 上使用此事件的简单示例。
$(document).on('hidden.bs.dropdown', function(event) {
console.log('closed');
});
现在我意识到这比被问到的一般问题更具体。但我想其他尝试使用 Bootstrap Dropdown 检测打开或关闭事件的开发人员会发现这很有帮助。像我一样,他们最初可能会走上简单地尝试检测元素类更改的道路(这显然不是那么简单)。谢谢。
如果您需要触发特定事件,您可以覆盖方法 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
// ...
});
您可以绑定 DOMSubtreeModified 事件。我在这里添加一个示例:
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');
});
});
if you know a what event changed the class in the first place you may use a slight delay on the same event and the check the for the class. example
//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');
});