Settimeout Keeps Firing
Solution 1:
In my_procedure() you can use
clearTimeout(timer);
in the first line to avoid multiple occurence
UPDATED CODE:
var target = document.body;
var timer;
var counter = 0;
var observer = newMutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
var count = mutation.addedNodes.length;
clearTimeout(timer);
if( count > 0) {
if(counter == 0){
counter = 1;
timer = setTimeout(function (){
console.log("executed");
my_procedure();
}, 500);
}else {
clearTimeout(timer);
}
}
});
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(target, config);
Solution 2:
The reason why setTimeout
seems to fire infinity, is that it actually fires as many times as there is e.g. new elements added to the DOM. So basically, it assigns 3 setTimeout
calls if 3 divs are added to the DOM. The reason being, that you are doing it inside mutations.forEach(function(mutation) { ... }
loop.
Therefore, the solution is to remove the loop and only assign one setTimeout
call at higher level which will fire when the DOM changes:
// create an observer instancevar observer = newMutationObserver(function(mutations) {
// fired when a mutation occurs
timer = setTimeout(function () {
console.log("executed");
// my_procedure();
}, 500);
});
Below is the full example, it should display "executed" once (after 3 second) to console when the DOM is actually changed, even though we add 3 new divs.
The code:
// select the target nodevar target = document.body,
timer;
// create an observer instancevar observer = newMutationObserver(function(mutations) {
// fired when a mutation occurs
timer = setTimeout(function () {
console.log("executed");
// my_procedure();
}, 500);
});
// configuration of the observer:var config = { attributes: true, childList: true, characterData: true };
// pass in the target node, as well as the observer options
observer.observe(target, config);
// Testing our observersetTimeout(function() {
document.body.innerHTML = "<div>lol 1</div>";
document.body.innerHTML += "<div>lol 2</div>";
document.body.innerHTML += "<div>lol 3</div>";
}, 3000);
/* Comment out if you want to add more divs..
setTimeout(function() {
document.body.innerHTML += "<div>lol 4</div>";
document.body.innerHTML += "<div>lol 5</div>";
document.body.innerHTML += "<div>lol 6</div>";
}, 5000);
*/
Cheers.
Solution 3:
You have got only 1 var "timer" and then you use ".forEach()" on your "mutations" !
So you overwrite timer each time, that's why if you set clearTimeout in my_procedure it doesn't work (it will stop only 1 timer, the last of the mutations).
Doesn't it ?
Post a Comment for "Settimeout Keeps Firing"