jQuery的火灾事件,如果CSS类改变

如果一个css类是用jQuery添加或更改的,我怎么能激发一个事件呢? 更改CSS类是否触发jQuery change()事件?

无论何时在脚本中更改某个类,都可以使用trigger来提升自己的事件。

 $(this).addClass('someClass'); $(mySelector).trigger('cssClassChanged') .... $(otherSelector).bind('cssClassChanged', data, function(){ do stuff }); 

但除此之外,不,在class级改变的时候,没有办法解决事件。 change()只在焦点离开一个input被改变的input之后触发。

 $(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> 

恕我直言,更好的解决scheme是结合@ 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 }); }); 

我build议你重写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 }); 

如果你想检测类的变化,最好的办法是使用突变观察者,这让你完全控制任何属性的变化。 但是,您需要自己定义侦听器,并将其附加到您正在侦听的元素。 好的是,一旦侦听器被追加,你不需要手动触发任何东西。

 $(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”监听器到你想观察的元素。

只是一个概念的certificate:

看看要点,看看一些注释并保持最新:

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'); 

当CSS类被添加或删除或定义改变时, change()不会触发。 在select或取消select某个select框的情况下,它会触发。

我不知道如果你的意思是如果CSS类的定义改变(这可以通过编程来完成,但是很乏味,而且一般不推荐)或者一个类被添加或删除到一个元素。 在这两种情况下都无法可靠地捕捉到这种情况。

你当然可以创build自己的事件,但这只能被形容为咨询 。 它不会捕获不属于你的代码。

或者,您可以重写/replacejQuery中的addClass() (etc)方法,但是当通过vanilla Javascript完成时,这不会捕获(尽pipe我猜你也可以replace这些方法)。

还有一种方法触发自定义事件

用于监视Html元素CSS变化的jQuery插件,作者:Rick Strahl

从上面引用

手表插件通过连接FireFox中的DOMAttrModified,Internet Explorer中的onPropertyChanged或通过使用带有setInterval的计时器来处理其他浏览器的更改检测。 不幸的是,WebKit目前不支持DOMAttrModified,因此Safari和Chrome目前必须使用较慢的setInterval机制。

好问题。 我使用Bootstrap下拉菜单,并且需要在隐藏Bootstrap下拉菜单时执行一个事件。 当打开下拉菜单时,类名为“button-group”的包含div将添加一个“open”类; 而button本身有一个“aria-expanded”属性设置为true。 当closures下拉菜单时,将从包含div中删除“open”类,并将aria-expanded从true切换为false。

这让我想到了如何检测class级变化的问题。

使用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检测一个打开或closures的事件会觉得这很有帮助。 和我一样,他们最初可能只是简单地尝试检测一个元素类的变化(这显然不是那么简单)。 谢谢。

如果你需要触发一个特定的事件,你可以重写方法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 // ... }); 

使用最新的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 }); 

//任何更新div的代码,如$ target.addClass('search-class');

您可以绑定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'); }); }); 

http://jsfiddle.net/hnCxK/13/

如果你知道一个事件发生了什么样的变化,那么你可以在同一个事件上稍微延迟一些,然后检查课程。 例

 //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); }); 

http://jsfiddle.net/GuDCp/3/

 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'); });