J'aimerais avoir quelque chose comme:
$('#myDiv').bind('class "submission ok" added'){
alert('class "submission ok" has been added');
});
Il n'y a pas d'événement déclenché quand une classe change. L'alternative consiste à déclencher manuellement un événement lorsque vous modifiez la classe par programme:
$someElement.on('event', function() {
$('#myDiv').addClass('submission-ok').trigger('classChange');
});
// in another js file, far, far away
$('#myDiv').on('classChange', function() {
// do stuff
});
UPDATE
Cette question semble rassembler quelques visiteurs, voici donc une mise à jour avec une approche qui peut être utilisée sans avoir à modifier le code existant à l'aide du nouveau 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>
Sachez que la MutationObserver
n'est disponible que pour les nouveaux navigateurs, en particulier Chrome 26, 14 FF, IE 11, Opera 15 et Safari 6. Voir MDN pour plus de détails. Si vous devez prendre en charge les anciens navigateurs, vous devrez utiliser la méthode que j'ai décrite dans mon premier exemple.
Vous pouvez remplacer les fonctions jQuery addClass et removeClass d’origine par les vôtres qui appellent les fonctions d’origine, puis déclenchent un événement personnalisé. (Utilisation d'une fonction anonyme invocante pour contenir la référence de fonction d'origine)
(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);
Ensuite, le reste de votre code sera aussi simple que vous le souhaiteriez.
$(selector).on('classChanged', function(){ /*...*/ });
Mise à jour:
Cette approche suppose que les classes ne seront modifiées que via les méthodes jQuery addClass et removeClass. Si les classes sont modifiées d'une autre manière (telle que la manipulation directe de l'attribut de classe via l'élément DOM), il serait nécessaire d'utiliser quelque chose comme MutationObserver
s, comme expliqué dans la réponse acceptée.
Aussi comme quelques améliorations à ces méthodes:
classAdded
) ou supprimée (classRemoved
) avec la classe spécifique transmise en tant qu'argument à la fonction de rappel et déclenchée uniquement si la classe particulière a été réellement ajouté (non présent auparavant) ou supprimé (était présent précédemment)Déclenchez uniquement classChanged
si des classes sont réellement modifiées
(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);
Avec ces fonctions de remplacement, vous pouvez ensuite gérer n'importe quelle classe modifiée via classChanged ou ajouter ou supprimer des classes spécifiques en vérifiant l'argument de la fonction de rappel:
$(document).on('classAdded', '#myElement', function(event, className) {
if(className == "something") { /* do something */ }
});
Utilisez trigger
pour déclencher votre propre événement. Chaque fois que vous changez de classe, ajoutez un déclencheur avec le nom
$("#main").on('click', function () {
$("#chld").addClass("bgcolorRed").trigger("cssFontSet");
});
$('#chld').on('cssFontSet', function () {
alert("Red bg set ");
});
vous pouvez utiliser quelque chose comme ceci:
$(this).addClass('someClass');
$(Selector).trigger('ClassChanged')
$(otherSelector).bind('ClassChanged', data, function(){//stuff });
mais sinon, non, il n'y a pas de fonction prédéfinie pour déclencher un événement quand une classe change.
En savoir plus sur les déclencheurs ici