是否可以收听“风格改变”事件?

IT技术 javascript jquery
2021-01-22 03:23:35

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

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

$('div').height(100); // yields '100'

这将非常有用。

有任何想法吗?

更新

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

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

这将临时覆盖内部的prototype.css 方法,并在最后用触发器重新定义它。所以它是这样工作的:

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

$('p').width(100);
$('p').css('color','red');
6个回答

自从提出这个问题以来,事情已经发生了一些变化 - 现在可以使用MutationObserver来检测元素的“样式”属性的变化,不需要 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'] });

传递给回调函数的参数是一个MutationRecord对象,可让您获取旧样式值和新样式值。

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

@bfred.it 您知道如何实现这一目标吗?我想在类的 css 规则应用于元素后运行一些 js。
2021-03-11 03:23:35
注意:MutationObserver 实际上并不适用于所有版本的 Android 4.4,不管 caniuse 怎么说。
2021-03-18 03:23:35
请记住,这仅适用于内联样式,不适用于由于类更改或@media更改而导致样式更改的情况。
2021-03-29 03:23:35
您可以使用getComputedStylewithsetInterval但这会大大降低您的网站速度。
2021-04-02 03:23:35
当 textarea 的宽度拉伸超过 300px 时,请参阅此 twiddle 的示例,将 textarea 的背景颜色更改为蓝色。jsfiddle.net/RyanNerd/y2q8wuf0 (不幸的是,FF 中似乎有一个错误将脚本挂在HTMLElement.style.prop = "value"
2021-04-03 03:23:35

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

这是此解决方案的完整示例:gist.github.com/bbottema/426810c21ae6174148d4
2021-03-26 03:23:35
但是在这种情况下,如果我直接使用 DOM 函数设置 style 属性会发生什么?
2021-04-06 03:23:35

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

(function() {
    orig = $.fn.css;
    $.fn.css = function() {
        var ev = new $.Event('style');
        orig.apply(this, arguments);
        $(this).trigger(ev);
    }
})();
它在执行此代码后不断触发,甚至没有达到要求的结果。
2021-03-21 03:23:35
太好了谢谢。有些人告诉更改原始来源,但您的扩展程序是最好的。我遇到了一些问题,但最终它起作用了。
2021-04-01 03:23:35

我认为最好的答案是来自 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;
    }
})();

用法

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

// Perform change
$('element').css('background', 'red');

我收到错误,因为 var ev = new $.Event('style'); HtmlDiv 中没有定义样式之类的东西。我删除了它,然后现在启动 $(this).trigger("stylechanged")。另一个问题是 Mike 没有返回 $(css, ..) 的结果,那么在某些情况下它可能会出现问题。所以我得到结果并返回它。现在可以使用 ^^ 在每个 css 更改中都包含一些我无法修改和触发事件的库。

非常有帮助和聪明
2021-03-17 03:23:35
就像在这个答案中提到的那样,如果事件不是从您的代码生成的,那么一种方法会有所帮助。请注意,这仅针对通过 jQuery 中的 css() 函数进行的更改。如果外部代码没有通过 css 函数进行更改,则永远不会调用事件处理程序。
2021-03-19 03:23:35

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

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

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

如果可以访问更改样式的代码,这确实是一个非常巧妙的解决方案。
2021-04-08 03:23:35