如何使用 jQuery 在类更改时触发事件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19401633/
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
How to fire an event on class change using jQuery?
提问by Matoeil
I would like to have something like:
我想要一些类似的东西:
$('#myDiv').bind('class "submission ok" added'){
alert('class "submission ok" has been added');
});
回答by Rory McCrossan
There is no event raised when a class changes. The alternative is to manually raise an event when you programatically change the class:
类更改时不会引发任何事件。另一种方法是在以编程方式更改类时手动引发事件:
$someElement.on('event', function() {
$('#myDiv').addClass('submission-ok').trigger('classChange');
});
// in another js file, far, far away
$('#myDiv').on('classChange', function() {
// do stuff
});
UPDATE
更新
This question seems to be gathering some visitors, so here is an update with an approach which can be used without having to modify existing code using the new MutationObserver
:
这个问题似乎吸引了一些访问者,所以这里有一种更新方法,无需使用 new 修改现有代码即可使用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>
Be aware that the MutationObserver
is only available for newer browsers, specifically Chrome 26, FF 14, IE 11, Opera 15 and Safari 6. See MDNfor more details. If you need to support legacy browsers then you will need to use the method I outlined in my first example.
请注意,MutationObserver
仅适用于较新的浏览器,特别是 Chrome 26、FF 14、IE 11、Opera 15 和 Safari 6。有关更多详细信息,请参阅MDN。如果您需要支持旧版浏览器,则需要使用我在第一个示例中概述的方法。
回答by Nickolas Hook
You could replace the original jQuery addClass and removeClass functions with your own that would call the original functions and then trigger a custom event. (Using a self-invoking anonymous function to contain the original function reference)
您可以用您自己的函数替换原来的 jQuery addClass 和 removeClass 函数,这些函数会调用原始函数,然后触发自定义事件。(使用自调用匿名函数包含原始函数引用)
(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);
Then the rest of your code would be as simple as you'd expect.
那么其余的代码将像您期望的一样简单。
$(selector).on('classChanged', function(){ /*...*/ });
Update:
更新:
This approach does make the assumption that the classes will only be changed via the jQuery addClass and removeClass methods. If classes are modified in other ways (such as direct manipulation of the class attribute through the DOM element) use of something like MutationObserver
s as explained in the accepted answer here would be necessary.
这种方法确实假设类只会通过 jQuery addClass 和 removeClass 方法进行更改。如果以其他方式修改类(例如通过 DOM 元素直接操作类属性),则需要使用MutationObserver
s之类的东西,如此处接受的答案中所述。
Also as a couple improvements to these methods:
也作为对这些方法的一些改进:
- Trigger an event for eachclass being added (
classAdded
) or removed (classRemoved
) with the specific class passed as an argument to the callback function and only triggered if the particular class was actually added (not present previously) or removed (was present previously) Only trigger
classChanged
if any classes are actually changed(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);
- 为每个添加 (
classAdded
) 或删除 (classRemoved
) 的类触发事件,并将特定类作为参数传递给回调函数,并且仅在实际添加(以前不存在)或删除(以前存在)特定类时触发 仅
classChanged
在实际更改任何类时触发(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);
With these replacement functions you can then handle any class changed via classChanged or specific classes being added or removed by checking the argument to the callback function:
使用这些替换函数,您可以通过检查回调函数的参数来处理通过 classChanged 更改的任何类或添加或删除的特定类:
$(document).on('classAdded', '#myElement', function(event, className) {
if(className == "something") { /* do something */ }
});
回答by Satinder singh
Use trigger
to fire your own event. When ever you change class add trigger with name
用trigger
火自己的事件。当您更改课程时,请添加带有名称的触发器
$("#main").on('click', function () {
$("#chld").addClass("bgcolorRed").trigger("cssFontSet");
});
$('#chld').on('cssFontSet', function () {
alert("Red bg set ");
});
回答by Deep Sharma
you can use something like this:
你可以使用这样的东西:
$(this).addClass('someClass');
$(Selector).trigger('ClassChanged')
$(otherSelector).bind('ClassChanged', data, function(){//stuff });
but otherwise, no, there's no predefined function to fire an event when a class changes.
但除此之外,不,没有预定义的函数可以在类更改时触发事件。
Read more about triggers here
在此处阅读有关触发器的更多信息