web-dev-qa-db-ja.com

DOM属性の変更時にイベントを発生させる

属性の変更時にイベント(カスタムの場合もある)をトリガーする方法はありますか?

IMG srcが変更されたとき、またはDIVのinnerHtmlが変更されたとしましょう。

62
ts.

注:2012年の時点で、突然変異イベントは標準から削除され、廃止されました。代替の使用方法については、他の回答またはドキュメントを参照してください MutationObserver

DOM Mutation Events を参照しています。これらのイベントに対するブラウザのサポートは貧弱ですが(改善されています)。 jQueryのMutation Eventsプラグイン は、あなたに道を開くかもしれません。

51
Dean Burge

MutationObserverのセットアップ方法。ほとんどは [〜#〜] mdn [〜#〜] からコピーされていますが、わかりやすくするために独自のコメントを追加しています。

window.MutationObserver = window.MutationObserver
    || window.WebKitMutationObserver
    || window.MozMutationObserver;
// Find the element that you want to "watch"
var target = document.querySelector('img'),
// create an observer instance
observer = new MutationObserver(function(mutation) {
     /** this is the callback where you
         do what you need to do.
         The argument is an array of MutationRecords where the affected attribute is
         named "attributeName". There is a few other properties in a record
         but I'll let you work it out yourself.
      **/
}),
// configuration of the observer:
config = {
    attributes: true // this is to watch for attribute changes.
};
// pass in the element you wanna watch as well as the options
observer.observe(target, config);
// later, you can stop observing
// observer.disconnect();

お役に立てれば。

39
Mats

特定の何かだけが必要な場合は、数ミリ秒ごとにターゲット属性をチェックすることにより、単純なsetInterval()が機能します。

var imgSrc = null;
setInterval(function () {
   var newImgSrc = $("#myImg").attr("src");
   if (newImgSrc !== imgSrc) {
      imgSrc = newImgSrc;
      $("#myImg").trigger("srcChange");
   }
}, 50);

次に、カスタムの「srcChange」イベントにバインドします。

$("#myImg").bind("srcChange", function () {....});
5
David Tang

フックできるネイティブdom変更イベントはありません。

良い記事 こちら jqueryプラグインの形でソリューションを提供しようとしています。

記事のコード

$.fn.watch = function(props, callback, timeout){
    if(!timeout)
        timeout = 10;
    return this.each(function(){
        var el      = $(this),
            func    = function(){ __check.call(this, el) },
            data    = { props:  props.split(","),
                        func:   callback,
                        vals:   [] };
        $.each(data.props, function(i) {
              data.vals[i] = el.css(data.props[i]); 
        });
        el.data(data);
        if (typeof (this.onpropertychange) == "object"){
            el.bind("propertychange", callback);
        } else if ($.browser.mozilla){
            el.bind("DOMAttrModified", callback);
        } else {
            setInterval(func, timeout);
        }
    });
    function __check(el) {
        var data    = el.data(),
            changed = false,
            temp    = "";
        for(var i=0;i < data.props.length; i++) {
            temp = el.css(data.props[i]);
            if(data.vals[i] != temp){
                data.vals[i] = temp;
                changed = true;
                break;
            }
        }
        if(changed && data.func) {
            data.func.call(el, data);
        }
    } }
4
redsquare

マッツの答え に加えて MDNのMutationObserverの使用例

options<property>: trueおよびMutationObserverのコールバック関数内でtargetのこのプロパティを変更する予定がある場合、次を使用して再帰呼び出しを防止します–スクリプトがタイムアウトするまで、スタックオーバーフローなど:

...
// Used to prevent recursive calls of observer's callback function
// From https://stackoverflow.com/questions/4561845/firing-event-on-dom-attribute-change
let insideInitialObserverCallback = false

let callback = function(mutationsList) {
    insideInitialObserverCallback = ! insideInitialObserverCallback
    if ( insideInitialObserverCallback ) {

        // ... change target's given property ...       

    }
})

let observer = new MutationObserver(callback);
...
0
Gerold Broser