在 jQuery 中触发 CSS 类更改的事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1950038/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Firing events on CSS class changes in jQuery
提问by user237060
How can I fire an event if a CSS class is added or changed using jQuery?
Does changing of a CSS class fire the jQuery change()
event?
如果使用 jQuery 添加或更改 CSS 类,如何触发事件?更改 CSS 类会触发 jQuerychange()
事件吗?
采纳答案by Jason
Whenever you change a class in your script, you could use a trigger
to raise your own event.
每当您更改脚本中的类时,您都可以使用 atrigger
来引发您自己的事件。
$(this).addClass('someClass');
$(mySelector).trigger('cssClassChanged')
....
$(otherSelector).bind('cssClassChanged', data, function(){ do stuff });
but otherwise, no, there's no baked-in way to fire an event when a class changes. change()
only fires after focus leaves an input whose input has been altered.
但除此之外,不,当班级发生变化时,没有内置的方式来触发事件。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>
回答by Arash Milani
IMHO the better solution is to combine two answers by @RamboNo5 and @Jason
恕我直言,更好的解决方案是结合@RamboNo5 和@Jason 的两个答案
I mean overridding addClass function and adding a custom event called cssClassChanged
我的意思是覆盖 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
});
});
回答by Mr Br
If you want to detect class change, best way is to use Mutation Observers, which gives you complete control over any attribute change. However you need to define listener yourself, and append it to element you are listening. Good thing is that you don't need to trigger anything manually once listener is appended.
如果您想检测类更改,最好的方法是使用 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
}
});
});
In this example event listener is appended to every element, but you don't want that in most cases (save memory). Append this "attrchange" listener to element you want observe.
在此示例中,事件侦听器附加到每个元素,但在大多数情况下您不希望这样(节省内存)。将此“attrchange”侦听器附加到您要观察的元素。
回答by RamboNo5
I would suggest you override the addClass function. You can do it this way:
我建议你覆盖 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
});
回答by yckart
Just a proof of concept:
只是一个概念证明:
Look at the gist to see some annotations and stay up-to-date:
查看要点以查看一些注释并保持最新状态:
https://gist.github.com/yckart/c893d7db0f49b1ea4dfb
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));
The usage is quite simple, just add a new listender on the node you want to observe and manipulate the classes as usually:
用法很简单,只需像往常一样在要观察和操作类的节点上添加一个新的侦听器:
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');
回答by Hassan Ali Shahzad
using latest jquery mutation
使用最新的 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
});
// any code which update div having class required-entrywhich is in $target like $target.addClass('search-class');
// 任何更新具有类required-entry 的div 的代码,该类在 $target 中,如 $target.addClass('search-class');
回答by Amitd
There is one more way withouttriggering an custom event
还有一种不触发自定义事件的方法
A jQuery Plug-in to monitor Html Element CSS Changes by Rick Strahl
Rick Strahl 用于监控 Html 元素 CSS 更改的 jQuery 插件
Quoting from above
从上面引用
The watch plug-in works by hooking up to DOMAttrModified in FireFox, to onPropertyChanged in Internet Explorer, or by using a timer with setInterval to handle the detection of changes for other browsers. Unfortunately WebKit doesn't support DOMAttrModified consistently at the moment so Safari and Chrome currently have to use the slower setInterval mechanism.
watch 插件的工作方式是连接到 FireFox 中的 DOMAttrModified,连接到 Internet Explorer 中的 onPropertyChanged,或者使用带有 setInterval 的计时器来处理其他浏览器的更改检测。不幸的是,WebKit 目前不支持 DOMAttrModified,因此 Safari 和 Chrome 当前必须使用较慢的 setInterval 机制。
回答by cletus
change()
does not fire when a CSS class is added or removed or the definition changes. It fires in circumstances like when a select box value is selected or unselected.
change()
添加或删除 CSS 类或定义更改时不会触发。它在诸如选择或未选择选择框值的情况下触发。
I'm not sure if you mean if the CSS class definition is changed (which can be done programmatically but is tedious and not generally recommended) or if a class is added or removed to an element. There is no way to reliably capture this happening in either case.
我不确定您的意思是 CSS 类定义是否已更改(可以通过编程方式完成,但很乏味且通常不推荐),或者是否在元素中添加或删除了类。在任何一种情况下,都无法可靠地捕获这种情况。
You could of course create your own event for this but this can only be described as advisory. It won't capture code that isn't yours doing it.
您当然可以为此创建自己的事件,但这只能被描述为咨询。它不会捕获不属于您的代码。
Alternatively you could override/replace the addClass()
(etc) methods in jQuery but this won't capture when it's done via vanilla Javascript (although I guess you could replace those methods too).
或者,您可以覆盖/替换addClass()
jQuery 中的(等)方法,但这不会在通过 vanilla Javascript 完成时捕获(尽管我猜您也可以替换这些方法)。
回答by Ken Palmer
Good question. I'm using the Bootstrap Dropdown Menu, and needed to execute an event when a Bootstrap Dropdown was hidden. When the dropdown is opened, the containing div with a class name of "button-group" adds a class of "open"; and the button itself has an "aria-expanded" attribute set to true. When the dropdown is closed, that class of "open" is removed from the containing div, and aria-expanded is switched from true to false.
好问题。我正在使用 Bootstrap 下拉菜单,并且需要在隐藏 Bootstrap 下拉菜单时执行一个事件。当下拉菜单打开时,包含类名为“button-group”的div添加了一个“open”类;并且按钮本身具有设置为 true 的“aria-expanded”属性。当下拉列表关闭时,“open”类将从包含的 div 中删除,并且 aria-expanded 从 true 切换到 false。
That led me to this question, of how to detect the class change.
这让我想到了这个问题,即如何检测班级变化。
With Bootstrap, there are "Dropdown Events" that can be detected. Look for "Dropdown Events" at this link. http://www.w3schools.com/bootstrap/bootstrap_ref_js_dropdown.asp
使用 Bootstrap,可以检测到“下拉事件”。在此链接中查找“下拉事件”。 http://www.w3schools.com/bootstrap/bootstrap_ref_js_dropdown.asp
Here is a quick-and-dirty example of using this event on a Bootstrap Dropdown.
这是在 Bootstrap Dropdown 上使用此事件的一个简单粗暴的示例。
$(document).on('hidden.bs.dropdown', function(event) {
console.log('closed');
});
Now I realize this is more specific than the general question that's being asked. But I imagine other developers trying to detect an open or closed event with a Bootstrap Dropdown will find this helpful. Like me, they may initially go down the path of simply trying to detect an element class change (which apparently isn't so simple). Thanks.
现在我意识到这比被问到的一般问题更具体。但我想其他试图使用 Bootstrap Dropdown 检测打开或关闭事件的开发人员会发现这很有帮助。像我一样,他们最初可能只是尝试检测元素类更改(这显然不是那么简单)。谢谢。
回答by Sativa Diva
You can bind the DOMSubtreeModified event. I add an example here:
您可以绑定 DOMSubtreeModified 事件。我在这里添加一个例子:
HTML
HTML
<div id="mutable" style="width:50px;height:50px;">sjdfhksfh<div>
<div>
<button id="changeClass">Change Class</button>
</div>
JavaScript
JavaScript
$(document).ready(function() {
$('#changeClass').click(function() {
$('#mutable').addClass("red");
});
$('#mutable').bind('DOMSubtreeModified', function(e) {
alert('class changed');
});
});