Reputation: 21
I am wondering if it's possible to listen for elements in DOM without using setInterval like I am doing it right now:
var interval = setInterval(() => {
var div = document.querySelector('.test');
if (div != null) {
clearInterval(interval);
console.log(div);
}
}, 1000);
My problem is that this specific div is loaded in DOM after 10-12 min randomly. And I think setInterval I just an ugly solution for this. So my question is, is it even possible to listen for new divs in DOM, without using interval?
Upvotes: 0
Views: 456
Reputation: 5486
This seems like a good job for Mutation Observer. It will observe a static parent on your DOM and alert you of any changes to the structure. You can listen for a child node with a class of test
to be added. For example:
// this setTimeout is only to show this example working. it is not needed
setTimeout(() => {
let aDiv = document.createElement('div');
aDiv.className = 'test';
document.getElementById('parent').appendChild(aDiv);
}, 3000);
let targetNode = document.getElementById('parent');
let config = {
attributes: false,
childList: true,
subtree: true
};
// Callback function to execute when mutations are observed
let callback = function(mutationsList, observer) {
for (let mutation of mutationsList) {
if (mutation.type == 'childList') {
for (let node of mutation.addedNodes) {
if (node.className === "test") {
console.log("a node with class test was added!");
// stop observing
observer.disconnect();
}
}
}
}
};
// Create an observer instance linked to the callback function
let observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(targetNode, config);
<div id="parent">
</div>
Upvotes: 3
Reputation: 2660
This can be achieved using CSS keyframe animations.
Javascript:
(function(){
var count = 1,
event = function(event){
if (event.animationName == 'nodeInserted')
event.target.textContent = 'Element ' + count++ + ' has been parsed!';
}
document.addEventListener('animationstart', event, false);
document.addEventListener('MSAnimationStart', event, false);
document.addEventListener('webkitAnimationStart', event, false);
// this is test code which imitates your div being created
// after a delay
setTimeout(function(){
var div = document.createElement('div');
div.setAttribute('class', 'some-control');
document.getElementById('test').appendChild(div)
}, 2000);
})();
CSS:
@keyframes nodeInserted {
from {
outline-color: #fff;
}
to {
outline-color: #000;
}
}
@-moz-keyframes nodeInserted {
from {
outline-color: #fff;
}
to {
outline-color: #000;
}
}
@-webkit-keyframes nodeInserted {
from {
outline-color: #fff;
}
to {
outline-color: #000;
}
}
@-ms-keyframes nodeInserted {
from {
outline-color: #fff;
}
to {
outline-color: #000;
}
}
@-o-keyframes nodeInserted {
from {
outline-color: #fff;
}
to {
outline-color: #000;
}
}
div.some-control {
padding: 50px;
background: #FF6A6A;
animation-duration: 0.01s;
-o-animation-duration: 0.01s;
-ms-animation-duration: 0.01s;
-moz-animation-duration: 0.01s;
-webkit-animation-duration: 0.01s;
animation-name: nodeInserted;
-o-animation-name: nodeInserted;
-ms-animation-name: nodeInserted;
-moz-animation-name: nodeInserted;
-webkit-animation-name: nodeInserted;
}
div.some-control div.some-control {
background: #87CEFF;
}
Credit to: http://www.backalleycoder.com/2012/04/25/i-want-a-damnodeinserted/
Upvotes: 1