在 DOM 元素的样式对象更改后,您可以使用 javascript 钩子触发器吗?

IT技术 javascript jquery css javascript-events
2021-02-27 17:58:23

一个元素有一个 javascriptstyle对象,其中包含 css 样式的不同名称和值。我想在每次这个对象改变而不使用 polling时触发一个函数有什么方法可以跨浏览器兼容并且可以与第三方代码一起可靠地工作(因为假设您正在提供插入脚本)?绑定一个 javascript 事件,比如DOMAttrModifiedor 是DOMSubtreeModified不够的,因为它们在 Chrome 中不起作用。

6个回答

编辑 4:现场演示

$(function() {
  $('#toggleColor').on('click', function() {
    $(this).toggleClass('darkblue');
  }).attrchange({
    trackValues: true,
    callback: function(event) {
      $(this).html("<ul><li><span>Attribute Name: </span>" + event.attributeName + "</li><li><span>Old Value: </span>" + event.oldValue + "</li><li><span>New Value: </span>" + event.newValue + "</li></ul>");
    }
  });
});
body {
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 12px;
}
#toggleColor {
  height: 70px;
  width: 300px;
  padding: 5px;
  border: 1px solid #c2c2c2;
  background-color: #DBEAF9;
}
#toggleColor span {
  font-weight: bold;
}
#toggleColor.darkblue {
  background-color: #1A9ADA;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://meetselva.github.io/attrchange/javascripts/attrchange.js"></script>
<p>Click below div to toggle class darkblue.</p>
<div id="toggleColor"></div>

编辑 3:我将所有这些放在一起作为一个插件,可以从 git attrchange下载,这里是演示页面

编辑2:

  1. 修复 IE7 和 IE8 中的属性名称

编辑1:

  1. 处理多个元素
  2. 将条件排序为 MutationObserver、DOMAttrModified 和 onpropertychange,以便更好地实现。
  3. 向回调添加了修改后的属性名称。

感谢@benvie 的反馈。

演示: http : //jsfiddle.net/zFVyv/10/(在 FF 12、Chrome 19 和 IE 7 中测试。)

$(function() {
    (function($) {
        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;

        function isDOMAttrModifiedSupported() {
            var p = document.createElement('p');
            var flag = false;

            if (p.addEventListener) p.addEventListener('DOMAttrModified', function() {
                flag = true
            }, false);
            else if (p.attachEvent) p.attachEvent('onDOMAttrModified', function() {
                flag = true
            });
            else return false;

            p.setAttribute('id', 'target');

            return flag;
        }

        $.fn.attrchange = function(callback) {
            if (MutationObserver) {
                var options = {
                    subtree: false,
                    attributes: true
                };

                var observer = new MutationObserver(function(mutations) {
                    mutations.forEach(function(e) {
                        callback.call(e.target, e.attributeName);
                    });
                });

                return this.each(function() {
                    observer.observe(this, options);
                });

            } else if (isDOMAttrModifiedSupported()) {
                return this.on('DOMAttrModified', function(e) {
                    callback.call(this, e.attrName);
                });
            } else if ('onpropertychange' in document.body) {
                return this.on('propertychange', function(e) {
                    callback.call(this, window.event.propertyName);
                });
            }
        }
    })(jQuery);

    $('.test').attrchange(function(attrName) {
        alert('Attribute: ' + attrName + ' modified ');
    }).css('height', 100);

});

参考:

  1. 检测是否支持 DOMAttrModified
  2. DOMAttrModified for chrome
  3. 突变观察者
  4. 为什么我们应该避免使用 Mutation 事件?
  5. onPropertyChange IE

Mutation Observers 是 DOM4 中突变事件的建议替代品。它们预计将包含在 Firefox 14 和 Chrome 18 中

浏览器支持:

onpropertychange - 支持 IE(在 IE 7 中测试)

DOMAttrModified - 支持 IE 9、FF 和 Opera

MutationObservers - 非常新,在Chrome 18 中运行良好不确定它在多大程度上受支持并且尚未在 Safari 中进行测试。

感谢@benvie添加有关 WebkitMutationObserver 的信息

哦,除非它也能处理无前缀版本(Firefox 15 支持)会更好。var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver.
2021-04-20 17:58:23
谢谢!什么是浏览器支持WebkitMutationObservers(它在 chrome 和 safari 中可以追溯到多远?)怎么样onPropertyChange
2021-04-24 17:58:23
不需要attachEvent分支isDOMAttrModifiedSupported:DOM 突变事件支持与addEventListenerIE 中的支持一致(两者都在 IE 9 中引入)。
2021-05-01 17:58:23
MutationObservers 是非常新的,但在最近的 WebKit 和 Firefox 中得到支持。不过,它们是 DOM 修改事件的未来,我很高兴看到它们包含在这个答案中。++这个答案
2021-05-05 17:58:23
@benvie 我在哪里可以找到支持它们的特定浏览器版本?
2021-05-13 17:58:23

编辑2:

如果你还想使用mutation observer,使用这个库:mutation-summary


编辑:

正如我在下面的回答中所说,并感谢 Vega 的评论,使用诸如object.watchmutation observers不推荐在大型应用程序中使用的东西这是MDN 的实际报价

一般情况下,您应该避免使用watch()unwatch()在可能的情况下。这两种方法仅在 Gecko 中实现,它们主要用于调试用途。此外,使用观察点 对性能有严重的负面影响,尤其是在全局对象上使用时尤其如此,例如窗口。您通常可以使用 settergetter代理代替。有关详细信息,请参阅兼容性。

警告

因此,如果跨浏览器兼容性在您的检查列表中,我再次强烈建议覆盖对象的setters 和getters style


object.watch在跨浏览器解决方案中 使用并牢记这些:

你可以覆盖gettersetter元素的方法style过于对象。

有一个 jQuery 插件可用于此,jQuery watch

@Vega 好吧,我不太了解 Gecko 的源代码,但我认为“轮询”OP 意味着手册setInterval,不是吗?
2021-05-06 17:58:23
我认为 watch 使用轮询......并且 OP 正在寻找对象更改而不使用轮询
2021-05-08 17:58:23

我发现这个小插件可以做到这一点,并且可以对其进行更改以添加您希望的任何突变……甚至 scrollHeight 更改侦听器。

插件:http : //www.jqui.net/jquery-projects/jquery-mutate-official/

这是演示:http : //www.jqui.net/demo/mutate/

这个插件使用了一种有趣的方法,但它确实使用了轮询(请参阅该setTimeout(reset, mutate.speed);行(您可能需要取消缩小以使其可读)。
2021-04-26 17:58:23

即使对于所有最现代的浏览器,也没有跨浏览器的方式来实现这一点。您必须通过一个可以触发事件侦听器的函数来路由所有 css 样式更改。这将是最干净的方法。

在对类似问题的回答中,有人建议如果您知道样式设置交互将通过标准接口执行(即始终使用 jQuery 等),则建议在调用库方法时触发自定义事件。

这将允许更广泛的支持矩阵,但如果在不使用库方法的情况下执行,则会忽略任何属性更改。这种方法似乎也不适用于本地 setter,因为它们不能总是被依赖。