如何使用 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 23:53:06  来源:igfitidea点击:

How to fire an event on class change using jQuery?

javascriptjqueryjavascript-events

提问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 MutationObserveris 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 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 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 classChangedif 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 triggerto fire your own event. When ever you change class add trigger with name

trigger火自己的事件。当您更改课程时,请添加带有名称的触发器

JS Fiddle DEMO

JS小提琴演示

$("#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 教程博客

回答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

在此处阅读有关触发器的更多信息