web-dev-qa-db-ja.com

DOM要素のスタイルオブジェクトが変更された後にjavascriptフックトリガーを使用できますか?

要素には、cssスタイルのさまざまな名前と値を含むjavascript styleオブジェクトがあります。このオブジェクトが変更されるたびに関数をトリガーしたいポーリングを使用せずに。クロスブラウザ互換で、サードパーティのコードで確実に機能する方法でこれを行う方法はありますか(ドロップインスクリプトを提供しているとしましょう)? DOMAttrModifiedDOMSubtreeModifiedのようなjavascriptイベントは、Chromeでは機能しないため、バインドするだけでは不十分です。

29
user730569

編集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のpropertNameの修正

編集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. ChromeのDOMAttrModified
  3. ミューテーションオブザーバー
  4. Mutationイベントの使用を避ける必要があるのはなぜですか?
  5. onPropertyChange IE

Mutation Observersは、DOM4のミューテーションイベントの代替案です。それらはFirefox14およびChrome 18

ブラウザサポート:

onpropertychange- IE(IE 7)でテスト済み)でサポートされています

DOMAttrModified- IE 9、FFおよびOperaでサポートされています

MutationObservers-は非常に新しく、 Chrome 18 で正常に機能しました。それがどこまでサポートされているかはわかりませんが、Safariではまだテストされていません。

ありがとう @ benvie WebkitMutationObserverに関する情報を追加してください

55

私はまさにそれを行うこの小さなプラグインを見つけました、そしてそれはあなたが望むどんな突然変異も加えるために変えることができます... scrollHeightさえリスナーを変えます。

プラグイン: http://www.jqui.net/jquery-projects/jquery-mutate-official/

ここにデモがあります: http://www.jqui.net/demo/mutate/

1
Val

attrchange jQueryプラグイン を使用できます。プラグインの主な機能は、HTML要素の属性変更時にリスナー関数をバインドすることです。

0
Muhammad Reda

最新のブラウザのすべてでさえ、これを達成するためのクロスブラウザの方法はありません。イベントリスナーをトリガーする可能性のある関数を介して、すべてのcssスタイルの変更をルーティングする必要があります。これが最もクリーンな方法です。

0
Steve Binder

同様の質問 への回答では、スタイル設定の相互作用が標準のインターフェイスを介して実行されることがわかっている場合(つまり、常にjQueryなどを使用)ライブラリメソッドが呼び出されるたびにカスタムイベントを発生させることが提案されました。

これにより、より広範なサポートマトリックスが可能になりますが、ライブラリメソッドを使用せずに実行した場合、プロパティの変更は無視されます。また、そのようなアプローチは、常に信頼できるとは限らないため、 ネイティブセッター には適用できないようです。

0
o.v.