Is it possible to listen to a “style change” event?

前端 未结 11 1122
南笙
南笙 2020-11-22 08:03

Is it possible to create an event listener in jQuery that can be bound to any style changes? For example, if I want to \"do\" something when an element changes dimensions, o

相关标签:
11条回答
  • 2020-11-22 08:37

    Interesting question. The problem is that height() does not accept a callback, so you wouldn't be able to fire up a callback. Use either animate() or css() to set the height and then trigger the custom event in the callback. Here is an example using animate() , tested and works (demo), as a proof of concept :

    $('#test').bind('style', function() {
        alert($(this).css('height'));
    });
    
    $('#test').animate({height: 100},function(){
    $(this).trigger('style');
    }); 
    
    0 讨论(0)
  • 2020-11-22 08:39

    I had the same problem, so I wrote this. It works rather well. Looks great if you mix it with some CSS transitions.

    function toggle_visibility(id) {
       var e = document.getElementById("mjwelcome");
       if(e.style.height == '')
          e.style.height = '0px';
       else
          e.style.height = '';
    }
    
    0 讨论(0)
  • 2020-11-22 08:41

    Just adding and formalizing @David 's solution from above:

    Note that jQuery functions are chainable and return 'this' so that multiple invocations can be called one after the other (e.g $container.css("overflow", "hidden").css("outline", 0);).

    So the improved code should be:

    (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
        }
    })();
    
    0 讨论(0)
  • 2020-11-22 08:43

    I think the best answer if from Mike in the case you can't launch your event because is not from your code. But I get some errors when I used it. So I write a new answer for show you the code that I use.

    Extension

    // Extends functionality of ".css()"
    // This could be renamed if you'd like (i.e. "$.fn.cssWithListener = func ...")
    (function() {
        orig = $.fn.css;
        $.fn.css = function() {
            var result = orig.apply(this, arguments);
            $(this).trigger('stylechanged');
            return result;
        }
    })();
    

    Usage

    // Add listener
    $('element').on('stylechanged', function () {
        console.log('css changed');
    });
    
    // Perform change
    $('element').css('background', 'red');
    

    I got error because var ev = new $.Event('style'); Something like style was not defined in HtmlDiv.. I removed it, and I launch now $(this).trigger("stylechanged"). Another problem was that Mike didn't return the resulto of $(css, ..) then It can make problems in some cases. So I get the result and return it. Now works ^^ In every css change include from some libs that I can't modify and trigger an event.

    0 讨论(0)
  • 2020-11-22 08:45

    Things have moved on a bit since the question was asked - it is now possible to use a MutationObserver to detect changes in the 'style' attribute of an element, no jQuery required:

    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'] });
    

    The argument that gets passed to the callback function is a MutationRecord object that lets you get hold of the old and new style values.

    Support is good in modern browsers including IE 11+.

    0 讨论(0)
提交回复
热议问题