Me gustaría tener algo como:
$('#myDiv').bind('class "submission ok" added'){
alert('class "submission ok" has been added');
});
Respuestas:
No se genera ningún evento cuando cambia una clase. La alternativa es generar manualmente un evento cuando cambia programáticamente la clase:
$someElement.on('event', function() {
$('#myDiv').addClass('submission-ok').trigger('classChange');
});
// in another js file, far, far away
$('#myDiv').on('classChange', function() {
// do stuff
});
ACTUALIZAR
Esta pregunta parece estar reuniendo a algunos visitantes, por lo que aquí hay una actualización con un enfoque que se puede usar sin tener que modificar el código existente usando el nuevo 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>
Tenga en cuenta que MutationObserversolo está disponible para los navegadores más nuevos, específicamente Chrome 26, FF 14, IE 11, Opera 15 y Safari 6. Consulte MDN para obtener más detalles. Si necesita admitir navegadores heredados, deberá utilizar el método que describí en mi primer ejemplo.
trigger()) aunque tenga en cuenta que está muy desactualizado debido al uso de bind(). Sin embargo, no estoy seguro de cómo 'completa' nada
MutationObserverfunciona para mí
Puede reemplazar las funciones jQuery addClass y removeClass originales con las suyas propias que llamarían a las funciones originales y luego activarían un evento personalizado. (Usando una función anónima autoinvocada para contener la referencia de función 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);
Entonces, el resto de su código sería tan simple como cabría esperar.
$(selector).on('classChanged', function(){ /*...*/ });
Actualizar:
Este enfoque supone que las clases solo se cambiarán a través de los métodos jQuery addClass y removeClass. Si las clases se modifican de otras maneras (como la manipulación directa del atributo de clase a través del elemento DOM) MutationObserver, sería necesario el uso de algo como s como se explica en la respuesta aceptada aquí.
También como un par de mejoras a estos métodos:
classAdded) o se elimina ( classRemoved) con la clase específica pasada como argumento a la función de devolución de llamada y solo se desencadena si la clase en particular fue realmente agregada (no presente previamente) o eliminada (estuvo presente previamente)Solo se activa classChangedsi se cambia alguna clase
(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);
Con estas funciones de reemplazo, puede manejar cualquier clase cambiada a través de classChanged o clases específicas que se agregan o eliminan al verificar el argumento de la función de devolución de llamada:
$(document).on('classAdded', '#myElement', function(event, className) {
if(className == "something") { /* do something */ }
});
$(parent_selector).on('classChanged', target_selector, function(){ /*...*/ });. Me tomó un tiempo ver por qué mis elementos creados dinámicamente no activaban el controlador. Ver learn.jquery.com/events/event-delegation
Úselo triggerpara disparar su propio evento. Siempre que cambie de clase, agregue un disparador con el nombre
$("#main").on('click', function () {
$("#chld").addClass("bgcolorRed").trigger("cssFontSet");
});
$('#chld').on('cssFontSet', function () {
alert("Red bg set ");
});
Aprenda jQuery: blog de tutoriales de jQuery simples y fáciles
puedes usar algo como esto:
$(this).addClass('someClass');
$(Selector).trigger('ClassChanged')
$(otherSelector).bind('ClassChanged', data, function(){//stuff });
pero de lo contrario, no, no hay una función predefinida para disparar un evento cuando cambia una clase.
Lea más sobre los desencadenantes aquí.