We can detect if an element has been added to DOM using the MutationObserver object. This provides the ability to observe for changes being made to the DOM tree.
Example
Consider the below markup where there is an element with ID parent. We would like to know when an element with ID child is inserted inside it.
<div id="parent"></div>
const observer = new MutationObserver(function(mutations_list) {
mutations_list.forEach(function(mutation) {
mutation.addedNodes.forEach(function(added_node) {
if(added_node.id == 'child') {
console.log('#child has been added');
observer.disconnect();
}
});
});
});
observer.observe(document.querySelector("#parent"), { subtree: false, childList: true });
- A new MutationObserver object is created. The observe() method starts observing DOM mutations taking #parent as the target.
- observe() method accepts various options as parameter. In this case 2 options are passed.
- subtree: false signifies that only the direct children of the target will be monitored. If we wish to monitor the entire tree of the target — children, grand-children, grand-grand-children, etc — then we would use subtree: true.
Note: Set this to false if the added element is a direct child of the target as monitoring the entire tree can be expensive. - childList: true signifies that addition & removal of child nodes will be monitored.
- The callback to the MutationObserver object receives an array of mutation records. Each such record contains addedNodes property that represents an array of nodes that were added.
- We can loop over the nodes in addedNodes to find out whether the added node matches our given criteria (in this case we are looking if element with ID child is present).
- Once we find that our intended element has been added to DOM, we can stop observing mutations using disconnect() method.
Once #child has been inserted, it will be detected.
// insert #child
document.querySelector("#parent").innerHTML = '<div id="child">Child</div>';
// '#child has been added'
Browser Compatibility
MutationObserver is supported in all browsers.