簡體   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