Eu gostaria de ter algo como:
$('#myDiv').bind('class "submission ok" added'){
alert('class "submission ok" has been added');
});
Respostas:
Nenhum evento é gerado quando uma classe muda. A alternativa é gerar manualmente um evento ao alterar programaticamente a classe:
$someElement.on('event', function() {
$('#myDiv').addClass('submission-ok').trigger('classChange');
});
// in another js file, far, far away
$('#myDiv').on('classChange', function() {
// do stuff
});
ATUALIZAR
Esta questão parece estar atraindo alguns visitantes, então aqui está uma atualização com uma abordagem que pode ser usada sem a necessidade de modificar o código existente usando o novo 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>
Esteja ciente de que o MutationObserverestá disponível apenas para navegadores mais recentes, especificamente Chrome 26, FF 14, IE 11, Opera 15 e Safari 6. Consulte MDN para obter mais detalhes. Se você precisar oferecer suporte a navegadores legados, precisará usar o método que descrevi no meu primeiro exemplo.
trigger()), embora observe que ela está muito desatualizada devido ao uso de bind(). Não tenho certeza de como isso 'completa' alguma coisa, no entanto
MutationObserverfunciona para mim
Você poderia substituir as funções addClass e removeClass originais do jQuery pelas suas próprias, que chamariam as funções originais e, em seguida, disparariam um evento personalizado. (Usando uma função anônima de auto-invocação para conter a referência da função original)
(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);
Então, o resto do seu código seria tão simples quanto você esperava.
$(selector).on('classChanged', function(){ /*...*/ });
Atualizar:
Essa abordagem pressupõe que as classes só serão alteradas por meio dos métodos jQuery addClass e removeClass. Se as classes forem modificadas de outras maneiras (como a manipulação direta do atributo de classe por meio do elemento DOM), use algo comoMutationObserver s, conforme explicado na resposta aceita aqui, seria necessário.
Além disso, algumas melhorias nesses métodos:
classAdded) ou removida (classRemoved ) com a classe específica passada como um argumento para a função de retorno de chamada e apenas acionado se a classe específica foi realmente adicionada (não presente anteriormente) ou removida (estava presente anteriormente)Só acionar classChangedse alguma classe for realmente alterada
(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);
Com essas funções de substituição, você pode manipular qualquer classe alterada via classChanged ou classes específicas adicionadas ou removidas, verificando o argumento da função de retorno de chamada:
$(document).on('classAdded', '#myElement', function(event, className) {
if(className == "something") { /* do something */ }
});
$(parent_selector).on('classChanged', target_selector, function(){ /*...*/ });. Levei um tempo para ver por que meus elementos criados dinamicamente não acionaram o manipulador. Consulte learn.jquery.com/events/event-delegation
Use triggerpara disparar seu próprio evento. Sempre que você mudar de classe, adicione o gatilho com o nome
$("#main").on('click', function () {
$("#chld").addClass("bgcolorRed").trigger("cssFontSet");
});
$('#chld').on('cssFontSet', function () {
alert("Red bg set ");
});
Aprenda jQuery: blog de tutoriais simples e fáceis de jQuery
você pode usar algo assim:
$(this).addClass('someClass');
$(Selector).trigger('ClassChanged')
$(otherSelector).bind('ClassChanged', data, function(){//stuff });
mas caso contrário, não, não há função predefinida para disparar um evento quando uma classe muda.
Leia mais sobre gatilhos aqui