有没有办法在属性更改时触发事件(可能是自定义)?
让我们说,当IMG src被更改或DIV的innerHtml?
答案 0 :(得分:50)
注意:截至2012年,Mutation Events已从标准中删除,现已弃用。请参阅其他答案或文档,了解如何使用替代品MutationObserver
。
您指的是DOM Mutation Events。这些事件的浏览器支持很差(但正在改进)。 Mutation Events plugin for jQuery可能会帮助你。
答案 1 :(得分:38)
如何设置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();
希望这有帮助。
答案 2 :(得分:5)
如果你只需要一些特定的东西,那么一个简单的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 () {....});
答案 3 :(得分:4)
没有可以挂钩的本地dom更改事件。
好文章here试图以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 :(得分:0)
除Mats' answer启发MDN's MutationObserver Example usage之外:
如果您的选项包含<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);
...
答案 5 :(得分:0)
我遇到了同样的问题,我必须找到某些特定DOM元素的track属性更改。我使用了MutationObserver。
但是在使用MutationObserver时,我还面临着另一种复杂性。 MutationObserver在观察变化时需要一些目标元素。
在使用SPA(使用AJAX,Angular,react或任何其他JavaScript框架)时,您可能已经意识到所有元素都是动态的。 那将很难设定目标。
这里提供了一些解决方案,其中我在DOM上应用了MutationObserver,然后在任何元素的某些属性发生更改时发出了customEvent。
然后按照我们的要求在下一步中过滤自定义事件。
// code to change image src in each 1000ms.
count = 0;
setInterval(function() {
dimension = `${600+count}x${400+count}`;
document.querySelector('div.image-box img').src = `https://dummyimage.com/${dimension}/000/fff`;
document.querySelector('div.image-box img').alt = dimension;
count++;
}, 1000);
function startMutationObserver(tNode, c) {
// Select the node that will be observed for mutations
const targetNode = tNode ? tNode : document;
// Options for the observer (which mutations to observe)
const config = c ? c : {
attributes: true,
childList: true,
subtree: true
};
// Callback function to execute when mutations are observed
const callback = function(mutationsList, observer) {
for (let mutation of mutationsList) {
if (mutation.type === 'childList') {
targetNode.dispatchEvent(new CustomEvent('newChild', {
detail: mutation
}));
} else if (mutation.type === 'attributes') {
targetNode.dispatchEvent(new CustomEvent('attributeChange', {
detail: mutation
}));
}
}
};
// Create an observer instance linked to the callback function
const observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(targetNode, config);
// Later, you can stop observing
// observer.disconnect();
}
// call this function to start observing DOM element change
startMutationObserver(document);
// code to listen custom event and filter custom event as per requirement
document.addEventListener('attributeChange', function(e) {
// console.log(e);
const ele = e.detail;
if (ele.target.matches('div.image-box img') && ele.attributeName == 'src') {
var src = e.detail.target.getAttribute('src');
var alt = e.detail.target.getAttribute('alt');
console.log(src, alt);
}
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div class="image-box">
<img src="https://dummyimage.com/600x400/000/fff" alt="600x400">
</div>
</body>
</html>
我希望这将帮助您跟踪任何属性更改,还可以插入新元素。 让我们尝试一下,让我知道您是否遇到任何问题。