Событие обжига при изменении атрибута DOM
Есть ли способ инициировать событие (может быть принято) при изменении атрибута?
Скажем, при изменении IMG src или DIV innerHtml?
Ответы
Ответ 1
Примечание. По состоянию на 2012 год события мутации были удалены из стандарта и теперь устарели. См. Другие ответы или документацию о том, как использовать их замену, MutationObserver
.
Вы имеете в виду DOM Mutation Events. Существует плохая (но улучшающая) поддержка браузера для этих событий. Плагин Mutation Events для jQuery может помочь вам в этом.
Ответ 2
Как настроить 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();
Надеюсь это поможет.
Ответ 3
Если вам нужно только что-то конкретное, тогда будет работать простой 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
Нет никакого измененного события, которое вы можете подключить.
Хорошая статья здесь, которая пытается предоставить решение в виде плагина 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);
}
} }
Ответ 5
В дополнение к ответу Матов, основанному на использовании MDN MutationObserver Пример использования:
Если ваши параметры содержат <property>: true
и вы планируете изменить это свойство цели внутри функции обратного вызова MutationObserver
, используйте для предотвращения рекурсивных вызовов: до истечения времени ожидания сценария, и т.п.:
...
// Used to prevent recursive calls of observer callback function
// From https://stackoverflow.com/info/4561845/firing-event-on-dom-attribute-change
let insideInitialObserverCallback = false
let callback = function(mutationsList) {
insideInitialObserverCallback = ! insideInitialObserverCallback
if ( insideInitialObserverCallback ) {
// ... change target given property ...
}
})
let observer = new MutationObserver(callback);
...