如何使用jQuery触发类更改事件?

时间:2022-12-03 22:09:31

I would like to have something like:

我希望有类似的东西:

$('#myDiv').bind('class "submission ok" added'){
    alert('class "submission ok" has been added');
});

4 个解决方案

#1


91  

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

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:

这个问题似乎聚集了一些访问者,所以这里有一个更新的方法,可以使用新的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 MDN for 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。如果您需要支持旧版浏览器,那么您需要使用我在第一个示例中概述的方法。

#2


15  

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 MutationObservers as explained in the accepted answer here would be necessary.

这种方法确实假设只能通过jQuery addClass和removeClass方法更改类。如果以其他方式修改类(例如通过DOM元素直接操作类属性),则需要使用MutationObservers之类的内容,如此处接受的答案中所述。

Also as a couple improvements to these methods:

此外,作为这些方法的一些改进:

  • Trigger an event for each class 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)
  • 为添加(classAdded)或删除(classRemoved)的每个类触发一个事件,并将特定类作为参数传递给回调函数,并且仅在特定类实际添加(之前不存在)或删除(之前存在)时触发
  • Only trigger classChanged if any classes are actually changed

    如果实际更改了任何类,则仅触发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 */ }
});

#3


6  

Use trigger to fire your own event. When ever you change class add trigger with name

使用触发器触发您自己的事件。什么时候更改类添加触发器的名称

JS Fiddle DEMO

JS Fiddle DEMO

$("#main").on('click', function () {
    $("#chld").addClass("bgcolorRed").trigger("cssFontSet");
});

$('#chld').on('cssFontSet', function () {

    alert("Red bg set ");
});

Learn jQuery: Simple and easy jQuery tutorials blog

学习jQuery:简单易用的jQuery教程博客

#4


2  

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

阅读更多关于触发器的信息

#1


91  

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

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:

这个问题似乎聚集了一些访问者,所以这里有一个更新的方法,可以使用新的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 MDN for 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。如果您需要支持旧版浏览器,那么您需要使用我在第一个示例中概述的方法。

#2


15  

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 MutationObservers as explained in the accepted answer here would be necessary.

这种方法确实假设只能通过jQuery addClass和removeClass方法更改类。如果以其他方式修改类(例如通过DOM元素直接操作类属性),则需要使用MutationObservers之类的内容,如此处接受的答案中所述。

Also as a couple improvements to these methods:

此外,作为这些方法的一些改进:

  • Trigger an event for each class 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)
  • 为添加(classAdded)或删除(classRemoved)的每个类触发一个事件,并将特定类作为参数传递给回调函数,并且仅在特定类实际添加(之前不存在)或删除(之前存在)时触发
  • Only trigger classChanged if any classes are actually changed

    如果实际更改了任何类,则仅触发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 */ }
});

#3


6  

Use trigger to fire your own event. When ever you change class add trigger with name

使用触发器触发您自己的事件。什么时候更改类添加触发器的名称

JS Fiddle DEMO

JS Fiddle DEMO

$("#main").on('click', function () {
    $("#chld").addClass("bgcolorRed").trigger("cssFontSet");
});

$('#chld').on('cssFontSet', function () {

    alert("Red bg set ");
});

Learn jQuery: Simple and easy jQuery tutorials blog

学习jQuery:简单易用的jQuery教程博客

#4


2  

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

阅读更多关于触发器的信息