Skip to content Skip to sidebar Skip to footer

Settimeout Keeps Firing

I have a simple chrome extension, which works with page's DOM (it looks for 'something' what looks like login forms). Problem is, that many pages has 'dynamic' login forms - its co

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.

js fiddle example

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"