J'aimerais avoir quelque chose comme:
$('#myDiv').bind('class "submission ok" added'){
alert('class "submission ok" has been added');
});
Réponses:
Aucun événement n'est déclenché lorsqu'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
});
MISE À JOUR
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 en utilisant le 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 le MutationObserver
n'est disponible que pour les navigateurs plus récents, en particulier Chrome 26, FF 14, IE 11, Opera 15 et Safari 6. Voir MDN pour plus de détails. Si vous devez prendre en charge les navigateurs hérités, vous devrez utiliser la méthode que j'ai décrite dans mon premier exemple.
trigger()
) bien que notez qu'elle est très obsolète en raison de l'utilisation de bind()
. Je ne sais pas comment cela `` complète '' quoi que ce soit
MutationObserver
fonctionne pour moi
Vous pouvez remplacer les fonctions jQuery addClass et removeClass d'origine par les vôtres qui appelleraient les fonctions d'origine, puis déclencheraient un événement personnalisé. (Utilisation d'une fonction anonyme auto-appelante 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 serait aussi simple que prévu.
$(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 par d'autres moyens (comme la manipulation directe de l'attribut class via l'élément DOM), l'utilisation de quelque chose comme MutationObserver
s comme expliqué dans la réponse acceptée ici serait nécessaire.
Aussi comme quelques améliorations à ces méthodes:
classAdded
) ou supprimée ( classRemoved
) avec la classe spécifique passée en argument à la fonction de rappel et déclenchée uniquement si la classe particulière a été réellement ajoutée (non présente précédemment) ou supprimée (était présente précédemment)Ne se déclenche que 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 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', '#myElement', function(event, className) {
if(className == "something") { /* do something */ }
});
$(parent_selector).on('classChanged', target_selector, function(){ /*...*/ });
. Il m'a fallu un certain temps pour voir pourquoi mes éléments créés dynamiquement n'ont pas déclenché le gestionnaire. Voir learn.jquery.com/events/event-delegation
Utilisez trigger
pour déclencher votre propre événement. Chaque fois que vous changez de classe, ajoutez un déclencheur avec un nom
$("#main").on('click', function () {
$("#chld").addClass("bgcolorRed").trigger("cssFontSet");
});
$('#chld').on('cssFontSet', function () {
alert("Red bg set ");
});
Apprendre jQuery: Blog de didacticiels jQuery simples et faciles
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 lorsqu'une classe change.
En savoir plus sur les déclencheurs ici