2013-10-16 82 views

回答

81

没有引发的事件当一个类的变化。另一种方法是手动触发一个事件,当您编程更改类:

$someElement.on('event', function() { 
    $('#myDiv').addClass('submission-ok').trigger('classChange'); 
}); 

// in another js file, far, far away 
$('#myDiv').on('classChange', function() { 
    // do stuff 
}); 

UPDATE

这个问题似乎是收集一些游客,所以这里是一个方法的更新,其中可以在不必修改现有代码的情况下使用新的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>

请注意,MutationObserver仅适用于较新的浏览器,例如Chrome浏览器26,FF 14,IE 11,歌剧15和Safari 6.请参阅MDN了解更多详情。如果您需要支持传统浏览器,那么您将需要使用我在第一个示例中列出的方法。

+0

在完成这个答案,我发现这个:https://stackoverflow.com/a/1950052/1579667 – Benj

+0

@Benj这是我的原始答案(即使用'触发器()')相同,但请注意,它是非常过时的,由于使用'bind()'。我不确定它是如何'完成'的,尽管 –

+0

确实如此,你是对的。 – Benj

2

你可以使用这样的事情:

$(this).addClass('someClass'); 

$(Selector).trigger('ClassChanged') 

$(otherSelector).bind('ClassChanged', data, function(){//stuff }); 

但除此之外,没有,没有预定义功能触发事件当一个类的变化。

了解更多关于触发器here

+1

事件的处理程序必须是触发事件的相同项目。 $(this).addClass('someClass'); ('ClassChanged'), //它必须是相同的选择器 $(Selector).bind('ClassChanged',data,function(){// stuff}); –

+2

似乎你已经从这里复制,如果是的话,那么如果你提供的链接太好也很好http://stackoverflow.com/questions/1950038/jquery-fire-event-if-css-class-changed/1950052#1950052 –

14

你可以用原来的函数替换原来的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); 

那么你的代码的其余部分是如你所期望的那样简单。

$(selector).on('classChanged', function(){ /*...*/ }); 

更新:

这种方法确实有这样的假设课程将只能通过jQuery的addClass与removeClass方法来改变。如果以其他方式修改类(例如通过DOM元素直接操作类属性),则可能需要使用类似MutationObserver s的东西,如接受的答案中所述。

另外,作为一对夫妇改进这些方法:

  • 触发为被添加的每个类(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); 
    

有了这些替代函数,那么你可以处理通过classChanged或特定类别改变任何类添加或删除通过检查参数的回调函数:

$(document).on('classAdded', '#myElement', function(event, className) { 
    if(className == "something") { /* do something */ } 
}); 
+1

这工作正常,但在“代码的其余部分”事件处理程序应委派给目标选择器以允许绑定到新元素:'$(parent_selector).on('classChanged',target_selector,function(){/ * ... * /});'。花了我一段时间,看看为什么我的动态创建的元素不会触发处理程序。请参阅http://learn.jquery.com/events/event-delegation/ – Timm