Est-il possible d'écouter un événement «changement de style»?

Est-il possible de créer un auditeur d'événement dans jQuery qui peut être lié à n'importe quel changement de style? Par exemple, si je veux "faire" quelque chose lorsqu'un élément change de dimension, ou tout autre changement dans l'attribut de style que je pourrais faire:

$('div').bind('style', function() { console.log($(this).css('height')); }); $('div').height(100); // yields '100' 

Ce serait vraiment utile.

Des idées?

METTRE À JOUR

Désolé de répondre à moi-même, mais j'ai écrit une solution soignée qui pourrait correspondre à quelqu'un d'autre:

 (function() { var ev = new $.Event('style'), orig = $.fn.css; $.fn.css = function() { $(this).trigger(ev); return orig.apply(this, arguments); } })(); 

Cela remplacera temporairement la méthode interne du prototype.css et la redéfinira avec un déclencheur à la fin. Donc, ça fonctionne comme ceci:

 $('p').bind('style', function(e) { console.log( $(this).attr('style') ); }); $('p').width(100); $('p').css('color','red'); 

Étant donné que jQuery est open-source, je suppose que vous pouvez modifier la fonction css pour appeler une fonction de votre choix chaque fois qu'elle est invoquée (en passant l'objet jQuery). Bien sûr, vous voudrez explorer le code jQuery pour s'assurer qu'il n'y a rien d'autre qu'il utilise en interne pour définir les propriétés CSS. Idéalement, vous souhaitez écrire un plugin séparé pour jQuery afin qu'il n'interfère pas avec la bibliothèque jQuery elle-même, mais vous devrez décider si cela est possible pour votre projet.

Les choses se sont déplacées un peu depuis que la question a été posée – il est maintenant possible d'utiliser un MutationObserver pour détecter les changements dans l'attribut 'style' d'un élément, aucun jQuery requis:

 var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutationRecord) { console.log('style changed!'); }); }); var target = document.getElementById('myId'); observer.observe(target, { attributes : true, attributeFilter : ['style'] }); 

L'argument qui passe à la fonction callback est un objet MutationRecord qui vous permet de saisir les anciennes et les nouvelles valeurs de style.

Le support est bon dans les navigateurs modernes, y compris IE 11+.

La déclaration de votre objet d'événement doit être dans votre nouvelle fonction css. Sinon, l'événement ne peut être lancé qu'une seule fois.

 (function() { orig = $.fn.css; $.fn.css = function() { var ev = new $.Event('style'); orig.apply(this, arguments); $(this).trigger(ev); } })(); 

Je pense que la meilleure réponse si de Mike dans le cas où vous ne pouvez pas lancer votre événement parce que cela ne provient pas de votre code. Mais j'ai des erreurs lorsque je l'ai utilisé. Donc, j'écris une nouvelle réponse pour vous montrer le code que j'utilise.

 (function() { orig = $.fn.css; $.fn.css = function() { var result = orig.apply(this, arguments); $(this).trigger("stylechanged"); return result; } })(); 

J'ai eu une erreur car var ev = new $ .Event ('style'); Quelque chose comme le style n'a pas été défini dans HtmlDiv .. Je l'ai supprimé, et je lance maintenant $ (this) .trigger ("stylechanged"). Un autre problème était que Mike n'a pas retourné le résultat de $ (css, ..) alors Il peut poser des problèmes dans certains cas. Je reçois donc le résultat et je le retourne. Maintenant, fonctionne ^^ Dans chaque modification css, incluez à partir de certaines libs que je ne peux pas modifier et déclencher un événement.

Comme d'autres l'ont suggéré, si vous avez le contrôle de tout code modifiant le style de l'élément, vous pouvez déclencher un événement personnalisé lorsque vous modifiez la hauteur de l'élément:

 $('#blah').bind('height-changed',function(){...}); ... $('#blah').css({height:'100px'}); $('#blah').trigger('height-changed'); 

Sinon, même si cela nécessite beaucoup de ressources, vous pouvez définir une minuterie pour vérifier périodiquement les modifications apportées à la hauteur de l'élément …

Il n'y a pas de support intégré pour l'événement de changement de style dans jQuery ou dans le script java. Mais jQuery prend en charge pour créer un événement personnalisé et l'écouter, mais chaque fois qu'il y a un changement, vous devriez avoir un moyen de le déclencher sur vous-même. Donc, ce ne sera pas une solution complète.

Question intéressante. Le problème est que height () n'accepte pas un rappel, donc vous ne pourrez pas lancer un rappel. Utilisez soit animate () ou css () pour définir la hauteur, puis déclenchez l'événement personnalisé dans le rappel. Voici un exemple utilisant animate (), testé et works ( demo ), comme preuve de concept:

 $('#test').bind('style', function() { alert($(this).css('height')); }); $('#test').animate({height: 100},function(){ $(this).trigger('style'); }); 

Il suffit d'ajouter et de formaliser la solution @David d'en haut:

Notez que les fonctions jQuery sont en chaîne et renvoient "ceci" afin que les invocations multiples puissent être appelées l'une après l'autre (p $container.css("overflow", "hidden").css("outline", 0); Ex. $container.css("overflow", "hidden").css("outline", 0); ).

Le code amélioré devrait donc être:

 (function() { var ev = new $.Event('style'), orig = $.fn.css; $.fn.css = function() { var ret = orig.apply(this, arguments); $(this).trigger(ev); return ret; // must include this } })(); 

J'ai eu le même problème, alors j'ai écrit ceci. Cela fonctionne plutôt bien. Aspire bien si vous le mélangez avec des transitions CSS.

 function toggle_visibility(id) { var e = document.getElementById("mjwelcome"); if(e.style.height == '') e.style.height = '0px'; else e.style.height = ''; } 

Vous pouvez essayer le plugin Jquery, il déclenche des événements lorsque CSS est un changement et est facile à utiliser.

 http://meetselva.github.io/#gist-section-attrchangeExtension 
  $([selector]).attrchange({ trackValues: true, callback: function (e) { //console.log( '<p>Attribute <b>' + e.attributeName +'</b> changed from <b>' + e.oldValue +'</b> to <b>' + e.newValue +'</b></p>'); //event.attributeName - Attribute Name //event.oldValue - Prev Value //event.newValue - New Value } });