是否可以倾听"风格变化"事件?

Dav*_*ing 190 javascript jquery

是否可以在jQuery中创建一个可以绑定到任何样式更改的事件侦听器?例如,如果我想在元素更改维度时"执行"某些操作,或者我可以执行样式属性中的任何其他更改:

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

$('div').height(100); // yields '100'
Run Code Online (Sandbox Code Playgroud)

这将非常有用.

有任何想法吗?

UPDATE

很抱歉自己回答这个问题,但我写了一个可能适合其他人的简洁解决方案:

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

这将临时覆盖内部prototype.css方法,并在最后用触发器重新定义它.它的工作原理如下:

$('p').bind('style', function(e) {
    console.log( $(this).attr('style') );
});

$('p').width(100);
$('p').css('color','red');
Run Code Online (Sandbox Code Playgroud)

cod*_*box 245

自提出问题以来,情况有所改变 - 现在可以使用MutationObserver来检测元素'style'属性的变化,不需要jQuery:

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'] });
Run Code Online (Sandbox Code Playgroud)

传递给回调函数的参数是MutationRecord对象,它允许您获取旧样式值和新样式值.

包括IE 11+在内的现代浏览器中,支持很好.

  • 请记住,这仅适用于内联样式,而不是由于类更改或"@media"更改而导致样式更改时. (17认同)
  • @ bfred.it你会想到如何实现这个目标吗?在将类的css规则应用于元素之后,我想要运行一些js. (2认同)

Jos*_*ola 19

由于jQuery是开源的,我猜你可以调整css函数来在每次调用时调用你选择的函数(传递jQuery对象).当然,您需要搜索jQuery代码以确保其内部没有任何其他内容用于设置CSS属性.理想情况下,你想为jQuery编写一个单独的插件,这样它就不会干扰jQuery库本身,但是你必须决定这对你的项目是否可行.

  • 但在这种情况下,如果我直接使用 DOM 函数设置 style 属性会发生什么? (3认同)

小智 18

事件对象的声明必须在新的css函数中.否则,事件只能被触发一次.

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


ccs*_*web 13

如果你不能发起你的活动,我认为最好的答案来自Mike,因为这不是来自你的代码.但是当我使用它时我遇到了一些错误.所以我写了一个新的答案,向您展示我使用的代码.

延期

// 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;
    }
})();
Run Code Online (Sandbox Code Playgroud)

用法

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

// Perform change
$('element').css('background', 'red');
Run Code Online (Sandbox Code Playgroud)

我得到错误因为var ev = new $ .Event('style'); 在HtmlDiv中没有​​定义类似样式的东西..我删除它,然后我现在启动$(this).trigger("stylechanged").另一个问题是迈克没有返回$(css,..)的结果然后它在某些情况下会出现问题.所以我得到了结果并将其返回.现在工作^^在每个css更改包括从一些我无法修改和触发事件的库.


dro*_*roo 5

正如其他人所建议的那样,如果您可以控制更改元素样式的任何代码,则可以在更改元素的高度时触发自定义事件:

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

否则,虽然非常耗费资源,但您可以设置一个计时器来定期检查元素高度的变化......