Chciałbym mieć coś takiego:
$('#myDiv').bind('class "submission ok" added'){
alert('class "submission ok" has been added');
});
Odpowiedzi:
W przypadku zmiany klasy nie jest wywoływane żadne zdarzenie. Alternatywą jest ręczne zgłoszenie zdarzenia, gdy programowo zmienisz klasę:
$someElement.on('event', function() {
$('#myDiv').addClass('submission-ok').trigger('classChange');
});
// in another js file, far, far away
$('#myDiv').on('classChange', function() {
// do stuff
});
AKTUALIZACJA
Wydaje się, że to pytanie przyciąga niektórych odwiedzających, więc oto aktualizacja z podejściem, które można zastosować bez konieczności modyfikowania istniejącego kodu za pomocą nowego 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>
Należy pamiętać, że MutationObserverjest dostępna tylko dla nowszych przeglądarek, w szczególności Chrome 26, FF 14, IE 11, Opera 15 i Safari 6. Więcej informacji można znaleźć w MDN . Jeśli potrzebujesz obsługiwać starsze przeglądarki, musisz użyć metody, którą przedstawiłem w moim pierwszym przykładzie.
trigger()), chociaż zauważ, że jest bardzo nieaktualna ze względu na użycie bind(). Nie jestem jednak pewien, jak to „kończy” cokolwiek
MutationObserverdziała dla mnie
Możesz zastąpić oryginalne funkcje jQuery addClass i removeClass własnymi, które wywoływałyby oryginalne funkcje, a następnie wyzwalały zdarzenie niestandardowe. (Używanie samowywołującej się funkcji anonimowej, aby zawierała odwołanie do oryginalnej funkcji)
(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);
Wtedy reszta kodu byłaby tak prosta, jak można by się spodziewać.
$(selector).on('classChanged', function(){ /*...*/ });
Aktualizacja:
To podejście zakłada, że klasy będą zmieniane tylko za pośrednictwem metod jQuery addClass i removeClass. Jeśli klasy są modyfikowane w inny sposób (np. Bezpośrednia manipulacja atrybutem klasy przez element DOM), MutationObserverkonieczne byłoby użycie czegoś takiego jak s, jak wyjaśniono w zaakceptowanej odpowiedzi tutaj.
Również jako kilka ulepszeń tych metod:
classAdded) lub usuwanej ( classRemoved) klasy z określoną klasą przekazaną jako argument do funkcji wywołania zwrotnego i wyzwalane tylko wtedy, gdy dana klasa została faktycznie dodana (wcześniej nieobecna) lub usunięta (była wcześniej obecna)Wyzwalaj tylko classChangedwtedy, gdy jakiekolwiek klasy zostaną faktycznie zmienione
(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);
Dzięki tym funkcjom zastępczym możesz obsłużyć dowolną klasę zmienioną przez classChanged lub dodać lub usunąć określone klasy, sprawdzając argument funkcji zwrotnej:
$(document).on('classAdded', '#myElement', function(event, className) {
if(className == "something") { /* do something */ }
});
$(parent_selector).on('classChanged', target_selector, function(){ /*...*/ });. Zajęło mi trochę czasu, aby zobaczyć, dlaczego moje dynamicznie tworzone elementy nie uruchomiły handlera. Zobacz learn.jquery.com/events/event-delegation
Służy triggerdo uruchamiania własnego wydarzenia. Kiedykolwiek zmienisz klasę, dodaj wyzwalacz z nazwą
$("#main").on('click', function () {
$("#chld").addClass("bgcolorRed").trigger("cssFontSet");
});
$('#chld').on('cssFontSet', function () {
alert("Red bg set ");
});
możesz użyć czegoś takiego:
$(this).addClass('someClass');
$(Selector).trigger('ClassChanged')
$(otherSelector).bind('ClassChanged', data, function(){//stuff });
ale poza tym nie, nie ma predefiniowanej funkcji uruchamiającej zdarzenie w przypadku zmiany klasy.
Przeczytaj więcej o wyzwalaczach tutaj