You can use a MutationObserver (check the compatibility ).
Consists of creating an object:
var miMO = new MutationObserver(callback);
And call observe(nodo, opciones)
with the node to be observed and options to determine when the callback is triggered. The options are a MutationObserverInit object that accepts:
-
childList
- If true, note additions and deletions of child nodes (including textNodes).
-
attributes
- If true, note the mutations in the attributes of the node.
-
characterData
- If true, note the mutations in the data of the node.
-
subtree
- If true, also observe the mutations in the descendants of the node.
-
attributeOldValue
- If true (with attributes
set to true), it triggers before the change in an attribute.
-
characterDataOldValue
- If true (with characterData
true), it triggers before the change in data.
-
attributeFilter
- An array of attributes if you just want to see a specific list.
The benefit of using a MutationObserver is that it fires with any modification to the DOM. It can be triggered when modifying from code, with a user's script, or even when the same user edits the DOM manually. For this reason, it is important that the filters passed as options are as specific as possible, so that the use of resources is not as intensive.
For example, to observe mutations in the src of an image:
var miImg = document.getElementById('idDeImg'),
miMO = new MutationObserver(callback);
miMO.observe(miImg, {
attributes: true,
attributeFilter: [
'src'
]
});
And then the callback will be called with a collection MutationRecord . In particular, for each element of the collection, we will be interested in verifying that .attributeName == "src"
. That is, that specific property has been changed. This check is redundant with the filters that we just passed, but I'll leave it in case you want to add another mutation that triggers the callback.
Example :
var miImg = document.getElementById('idDeImg'),
miMO = new MutationObserver(callbackMO);
miMO.observe(miImg, {
attributes: true,
attributeOldValue: true,
attributeFilter: ['src']
});
function callbackMO(mutations) {
mutations.forEach((mutation) => {
if (mutation.attributeName == "src") { // <- redundante
console.log('Se cambió la imagen de', mutation.oldValue, 'a', mutation.target.src);
}
});
}
//Prueba cambiando el src
function cambiarSrc() {
miImg.src = "https://i.stack.imgur.com/f4AWis.jpg";
}
<img id="idDeImg" src="https://i.stack.imgur.com/knEtbs.jpg">
<br>
<input type="button" onclick="cambiarSrc()" value="Probar cambiar el src">