2013-10-16 31 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