繁体   English   中英

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

[英]Can you have a JavaScript hook trigger after a DOM element's style object changes?

一个元素有一个 JavaScript style对象,其中包含 CSS 样式的不同名称和值。 我想在不使用 polling 的情况下每次更改此对象时触发一个函数。 有没有办法以跨浏览器兼容的方式做到这一点,并且可以可靠地与第三方代码一起工作(因为假设您正在提供一个插入式脚本)? 绑定DOMAttrModifiedDOMSubtreeModified类的 JavaScript 事件是不够的,因为它们在 Chrome 中不起作用。

编辑 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 的信息

编辑2:

如果您仍想使用mutation observer ,请使用此库: mutation-summary


编辑:

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

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

警告

因此,如果您的检查清单中有跨浏览器兼容性,我强烈建议您覆盖style对象的settergetter


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

您也可以覆盖元素style对象的gettersetter方法。

有一个可用的 jQuery 插件, jQuery watch

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

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

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

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

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

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

您可以使用attrchange jQuery 插件 该插件的主要功能是绑定一个HTML元素属性变化的监听函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM