Şunun gibi bir şeye sahip olmak istiyorum:
$('#myDiv').bind('class "submission ok" added'){
alert('class "submission ok" has been added');
});
Yanıtlar:
Bir sınıf değiştiğinde ortaya çıkan bir olay yoktur. Alternatif, sınıfı programatik olarak değiştirdiğinizde bir olayı manuel olarak yükseltmektir:
$someElement.on('event', function() {
$('#myDiv').addClass('submission-ok').trigger('classChange');
});
// in another js file, far, far away
$('#myDiv').on('classChange', function() {
// do stuff
});
GÜNCELLEME
Bu soru, bazı ziyaretçileri topluyor gibi görünüyor, bu nedenle, yenisini kullanarak mevcut kodu değiştirmek zorunda kalmadan kullanılabilecek bir yaklaşımla güncelleme 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>
Unutmayın MutationObserver
özellikle Krom 26 FF 14, IE 11 yeni tarayıcılarda için kullanılabilir, Opera 15 ve Safari 6. Bkz MDN fazla ayrıntı için. Eski tarayıcıları desteklemeniz gerekiyorsa, ilk örneğimde özetlediğim yöntemi kullanmanız gerekecektir.
trigger()
), ancak kullanımı nedeniyle çok eski olduğuna dikkat edin bind()
. Yine de her şeyi nasıl 'tamamladığından' emin değilim
MutationObserver
benim için çalıştığı belirli bir sınıf olduğunda bir olayı
Orijinal jQuery addClass ve removeClass işlevlerini, orijinal işlevleri çağıran ve ardından özel bir olayı tetikleyen kendi işlevlerinizle değiştirebilirsiniz. (Orijinal işlev referansını içermek için kendi kendini çağıran bir anonim işlevi kullanma)
(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);
O zaman kodunuzun geri kalanı beklediğiniz kadar basit olacaktır.
$(selector).on('classChanged', function(){ /*...*/ });
Güncelleme:
Bu yaklaşım, sınıfların yalnızca jQuery addClass ve removeClass yöntemleri aracılığıyla değiştirileceği varsayımını yapar. Sınıflar başka şekillerde değiştirilirse (sınıf özniteliğinin DOM öğesi aracılığıyla doğrudan işlenmesi gibi MutationObserver
), burada kabul edilen yanıtta açıklandığı gibi s gibi bir şeyin kullanılması gerekli olacaktır.
Ayrıca bu yöntemlerde birkaç iyileştirme olarak:
classAdded
classRemoved
Yalnızca classChanged
herhangi bir sınıf gerçekten değiştirilirse tetikleyin
(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);
Bu değiştirme işlevleriyle, geri çağrı işlevine argümanı kontrol ederek, classChanged aracılığıyla değiştirilen herhangi bir sınıfı veya eklenen veya kaldırılan belirli sınıfları işleyebilirsiniz:
$(document).on('classAdded', '#myElement', function(event, className) {
if(className == "something") { /* do something */ }
});
$(parent_selector).on('classChanged', target_selector, function(){ /*...*/ });
. Dinamik olarak oluşturduğum unsurların neden işleyiciyi ateşlemediğini anlamam biraz zaman aldı. See learn.jquery.com/events/event-delegation
trigger
Kendi olayınızı ateşlemek için kullanın . Sınıfı değiştirdiğinizde adı olan tetikleyici ekleyin
$("#main").on('click', function () {
$("#chld").addClass("bgcolorRed").trigger("cssFontSet");
});
$('#chld').on('cssFontSet', function () {
alert("Red bg set ");
});
bunun gibi bir şey kullanabilirsiniz:
$(this).addClass('someClass');
$(Selector).trigger('ClassChanged')
$(otherSelector).bind('ClassChanged', data, function(){//stuff });
ancak aksi takdirde hayır, sınıf değiştiğinde bir olayı tetikleyecek önceden tanımlanmış bir işlev yoktur.
Tetikleyiciler hakkında daha fazlasını buradan okuyun