Je voudrais avoir quelque chose comme:
$('#myDiv').bind('class "soumission ok" ajouté'){
alert('class "soumission ok" a été ajouté');
});
Je voudrais avoir quelque chose comme:
$('#myDiv').bind('class "soumission ok" ajouté'){
alert('class "soumission ok" a été ajouté');
});
Il n'y a pas d'événement déclenché lorsqu'une classe change. L'alternative est de déclencher manuellement un événement lorsque vous changez le class programmatiquement :
$someElement.on('event', function() {
$('#myDiv').addClass('submission-ok').trigger('classChange');
});
// dans un autre fichier js, loin, très loin
$('#myDiv').on('classChange', function() {
// faire quelque chose
});
MISE À JOUR - 2015
Cette question semble attirer quelques visiteurs, voici donc une mise à jour avec une approche qui peut être utilisée sans avoir à modifier le code existant en utilisant le nouveau MutationObserver
:
var $div = $("#foo");
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
var attributeValue = $(mutation.target).prop(mutation.attributeName);
console.log("La classe de l'attribut a été changée en :", attributeValue);
});
});
observer.observe($div[0], {
attributes: true,
attributeFilter: ['class']
});
$div.addClass('red');
.red {
color: #C00;
}
#foo.bar
Sachez que le MutationObserver
est uniquement disponible pour les navigateurs plus récents, spécifiquement Chrome 26, FF 14, IE 11, Opera 15 et Safari 6. Consultez la MDN pour plus de détails. Si vous avez besoin de prendre en charge les anciens navigateurs, vous devrez utiliser la méthode que j'ai décrite dans mon premier exemple.
MISE À JOUR - 2022
Voici une implémentation de ce qui précède enveloppée dans une méthode d'extension jQuery :
// méthode d'extension :
$.fn.onClassChange = function(cb) {
return $(this).each((_, el) => {
new MutationObserver(mutations => {
mutations.forEach(mutation => cb && cb(mutation.target, mutation.target.className));
}).observe(el, {
attributes: true,
attributeFilter: ['class'] // écouter uniquement les changements d'attribut de classe
});
});
}
// utilisation :
const $foo = $("#foo").onClassChange((el, newClass) => console.log(`#${el.id} a été mis à jour avec la classe : ${newClass}`));
const $fizz = $("#fizz").onClassChange((el, newClass) => console.log(`#${el.id} a été mis à jour avec la classe : ${newClass}`));
// déclencher
$('#trigger').on('click', () => {
$foo.removeClass('red');
$fizz.addClass('green dark-bg');
});
.red {
color: #C00;
}
.green {
color: #0C0;
}
.dark-bg {
background-color: #666;
}
Changer les classes
#foo.bar
#fizz.buzz
Vous pourriez remplacer les fonctions d'origine jQuery addClass et removeClass par les vôtres qui appeleraient les fonctions d'origine, puis déclencheraient un événement personnalisé. (Utilisation d'une fonction anonyme auto-invoquante pour contenir la référence de la fonction d'origine)
(function( func ) {
$.fn.addClass = function() { // remplacer la fonction existante sur $.fn
func.apply( this, arguments ); // appeler la fonction d'origine
this.trigger('classChanged'); // déclencher l'événement personnalisé
return this; // conserver la chaînabilité de jQuery
}
})($.fn.addClass); // passer la fonction d'origine en argument
(function( func ) {
$.fn.removeClass = function() {
func.apply( this, arguments );
this.trigger('classChanged');
return this;
}
})($.fn.removeClass);
Ensuite, le reste de votre code serait aussi simple que vous vous y attendez.
$(sélecteur).on('classChanged', function(){ /*...*/ });
Mise à jour :
Cette approche suppose que les classes seront modifiées uniquement via les méthodes jQuery addClass et removeClass. Si les classes sont modifiées d'autres façons (comme la manipulation directe de l'attribut de classe à travers l'élément DOM), l'utilisation de quelque chose comme les MutationObserver
s comme expliqué dans la réponse acceptée ici serait nécessaire.
Aussi, pour quelques améliorations à ces méthodes :
Déclencher un événement pour chaque classe ajoutée (classAdded
) ou supprimée (classRemoved
) avec la classe spécifique passée en argument à la fonction de rappel et déclencher seulement si la classe particulière a réellement été ajoutée (n'était pas présente auparavant) ou supprimée (était présente auparavant)
Ne déclencher classChanged
que si des classes sont effectivement modifiées
(function( func ) {
$.fn.addClass = function(n) { // remplacer la fonction existante sur $.fn
this.each(function(i) { // pour chaque élément dans la collection
var $this = $(this); // 'this' est l'élément DOM dans ce contexte
var prevClasses = this.getAttribute('class'); // noter ses classes d'origine
var classNames = $.isFunction(n) ? n(i, prevClasses) : n.toString(); // maintenir la prise en charge des arguments de type fonction
$.each(classNames.split(/\s+/), function(index, className) { // permettre l'ajout de plusieurs classes
if( !$this.hasClass(className) ) { // seulement quand la classe n'est pas déjà présente
func.call( $this, className ); // appeler la fonction d'origine pour ajouter la classe
$this.trigger('classAdded', className); // déclencher un événement classAdded
}
});
if( prevClasses != this.getAttribute('class') ) $this.trigger('classChanged'); // déclencher l'événement classChanged
});
return this; // conserver la chaînabilité de jQuery
}
})($.fn.addClass); // passer la fonction d'origine en 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);
}
});
if( prevClasses != this.getAttribute('class') ) $this.trigger('classChanged');
});
return this;
}
})($.fn.removeClass);
Avec ces fonctions de remplacement, vous pouvez ensuite gérer toute classe modifiée via classChanged ou des classes spécifiques ajoutées ou supprimées en vérifiant l'argument de la fonction de rappel :
$(document).on('classAdded', '#monElement', function(event, className) {
if(className == "quelquechose") { /* faire quelque chose */ }
});
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 lorsque une classe change.
En savoir plus sur les déclencheurs ici
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.