событие срабатывания при изменении атрибута DOM - PullRequest
61 голосов
/ 30 декабря 2010

есть ли способ вызвать событие (может быть пользовательским) при изменении атрибута?

Скажем, когда изменяется IMG src или innerHtml DIV?

Ответы [ 5 ]

50 голосов
/ 30 декабря 2010

Примечание. С 2012 года события мутации удалены из стандарта и теперь устарели.См. Другие ответы или документацию о том, как использовать их замену, MutationObserver.

Вы имеете в виду События мутации DOM .Слабая (но улучшающаяся) поддержка браузеров для этих событий. Плагин Mutation Events для jQuery может помочь вам.

38 голосов
/ 30 марта 2014

Как настроить 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();

Надеюсь, это поможет.

5 голосов
/ 30 декабря 2010

Если вам нужно только что-то конкретное, тогда будет работать простой 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 () {....});
4 голосов
/ 30 декабря 2010

Нет такого события, в которое вы можете зайти.

Хорошая статья здесь , которая пытается предоставить решение в виде плагина 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);
        }
    } }
0 голосов
/ 03 февраля 2018

В дополнение к ответу Матса , вдохновленному примером использования MDN MutationObserver :

Если ваши параметры содержат <property>: true и вы планируете изменить это свойство target внутри функции обратного вызова MutationObserver, используйте следующее для предотвращения рекурсивных вызовов - до сценария тайм-аут, переполнение стека или тому подобное:

...
// Used to prevent recursive calls of observer's callback function
// From /3400452/sobytie-srabatyvaniya-pri-izmenenii-atributa-dom
let insideInitialObserverCallback = false

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

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

    }
})

let observer = new MutationObserver(callback);
...
...