Javascript setTimeout持续启动

Javascript setTimeout持续启动,javascript,dom,settimeout,Javascript,Dom,Settimeout,我有一个简单的chrome扩展,它与页面的DOM一起工作(它寻找类似于登录表单的“某物”)。问题是,许多页面都有“动态”登录表单——它的代码会在需要时隐藏起来。这就是为什么body的onload事件是不够的 因此,我创建了变异观察者,并在每次DOM更改时执行我的过程(将来会有一些限制-其中许多更改不会影响我的目的) 由于某些时间间隔,我必须在更新的DOM上延迟执行我的过程(时间500仅用于测试目的) 问题是,setTimeout一直激发到无穷大,这使得页面在一段时间后变得非常懒惰。在Chrome

我有一个简单的chrome扩展,它与页面的DOM一起工作(它寻找类似于登录表单的“某物”)。问题是,许多页面都有“动态”登录表单——它的代码会在需要时隐藏起来。这就是为什么body的onload事件是不够的

因此,我创建了变异观察者,并在每次DOM更改时执行我的过程(将来会有一些限制-其中许多更改不会影响我的目的)

由于某些时间间隔,我必须在更新的DOM上延迟执行我的过程(时间500仅用于测试目的)

问题是,setTimeout一直激发到无穷大,这使得页面在一段时间后变得非常懒惰。在ChromeJS控制台中,“已执行”消息的数量仍在增加

我知道
clearTimeout(timer)
,但我不能正确使用它-因此
myu过程
对于每个DOM更改只执行一次

编辑:
my_过程
实际上是第三方库函数,因此我不想(或可以)更改它-该函数启动整个表单分类逻辑

谢谢您的建议。

在my_过程()中,您可以使用

clearTimeout(timer); 
在第一行中,以避免多次发生

更新代码:

var target = document.body;
var timer;
var counter = 0;

var observer = new MutationObserver(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);
// select the target node
var target = document.body,
    timer;

// create an observer instance
var observer = new MutationObserver(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 observer
setTimeout(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);
*/
在my_procedure()中,您可以使用

clearTimeout(timer); 
在第一行中,以避免多次发生

更新代码:

var target = document.body;
var timer;
var counter = 0;

var observer = new MutationObserver(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);
// select the target node
var target = document.body,
    timer;

// create an observer instance
var observer = new MutationObserver(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 observer
setTimeout(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);
*/
在my_procedure()中,您可以使用

clearTimeout(timer); 
在第一行中,以避免多次发生

更新代码:

var target = document.body;
var timer;
var counter = 0;

var observer = new MutationObserver(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);
// select the target node
var target = document.body,
    timer;

// create an observer instance
var observer = new MutationObserver(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 observer
setTimeout(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);
*/
在my_procedure()中,您可以使用

clearTimeout(timer); 
在第一行中,以避免多次发生

更新代码:

var target = document.body;
var timer;
var counter = 0;

var observer = new MutationObserver(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);
// select the target node
var target = document.body,
    timer;

// create an observer instance
var observer = new MutationObserver(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 observer
setTimeout(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);
*/
您只有1个变量“timer”,然后在“translations”上使用“.forEach()”

所以每次都会覆盖计时器,这就是为什么如果在my_过程中设置clearTimeout,它将不起作用(它将只停止1个计时器,即最后一个突变)

不是吗?

您只有1个变量“timer”,然后在“translations”上使用“.forEach()”

所以每次都会覆盖计时器,这就是为什么如果在my_过程中设置clearTimeout,它将不起作用(它将只停止1个计时器,即最后一个突变)

不是吗?

您只有1个变量“timer”,然后在“translations”上使用“.forEach()”

所以每次都会覆盖计时器,这就是为什么如果在my_过程中设置clearTimeout,它将不起作用(它将只停止1个计时器,即最后一个突变)

不是吗?

您只有1个变量“timer”,然后在“translations”上使用“.forEach()”

所以每次都会覆盖计时器,这就是为什么如果在my_过程中设置clearTimeout,它将不起作用(它将只停止1个计时器,即最后一个突变)


是吗?

setTimeout似乎触发无穷大的原因是它实际触发的次数与添加到DOM中的新元素的次数相同。因此,基本上,如果向DOM添加3个div,它将分配3个
setTimeout
调用。原因是,您是在
translations.forEach(function(mutation){…}
循环中进行的

因此,解决方案是删除循环,只在更高级别上分配一个
setTimeout
调用,当DOM更改时将触发该调用:

// create an observer instance
var observer = new MutationObserver(function(mutations) {

   // fired when a mutation occurs
   timer = setTimeout(function () {

      console.log("executed");
      // my_procedure();

   }, 500);  

});
下面是完整的示例,当DOM实际更改时,即使我们添加了3个新的div,它也应该在控制台上显示“executed”一次(3秒后)

代码:

var target = document.body;
var timer;
var counter = 0;

var observer = new MutationObserver(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);
// select the target node
var target = document.body,
    timer;

// create an observer instance
var observer = new MutationObserver(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 observer
setTimeout(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);
*/
//选择目标节点
var target=document.body,
定时器;
//创建一个观察者实例
var观察者=新的突变观察者(功能(突变){
//当突变发生时激发
定时器=设置超时(函数(){
控制台日志(“已执行”);
//我的程序();
}, 500);  
});
//观察员的配置:
var config={attributes:true,childList:true,characterData:true};
//传入目标节点以及观察者选项
observer.observe(目标,配置);
//测试我们的观察者
setTimeout(函数(){
document.body.innerHTML=“lol 1”;
document.body.innerHTML+=“lol 2”;
document.body.innerHTML+=“lol 3”;
}, 3000);
/*如果要添加更多div,请将其注释掉。。
setTimeout(函数(){
document.body.innerHTML+=“lol 4”;
document.body.innerHTML+=“lol 5”;
document.body.innerHTML+=“lol 6”;
}, 5000);
*/

干杯。

为什么
setTimeout
似乎激发无穷大,是因为它实际上激发的次数与DOM中添加新元素的次数相同。因此,基本上,如果向DOM中添加了3个div,它将分配3个
setTimeout
调用。原因是,您在
突变中执行此操作。forEach(函数(突变){…}
循环

因此,解决方案是删除循环,只在更高级别上分配一个
setTimeout
调用,当DOM更改时将触发该调用:

// create an observer instance
var observer = new MutationObserver(function(mutations) {

   // fired when a mutation occurs
   timer = setTimeout(function () {

      console.log("executed");
      // my_procedure();

   }, 500);  

});
下面是完整的示例,当DOM实际更改时,即使我们添加了3个新的div,它也应该在控制台上显示“executed”一次(3秒后)

代码:

var target = document.body;
var timer;
var counter = 0;

var observer = new MutationObserver(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);
// select the target node
var target = document.body,
    timer;

// create an observer instance
var observer = new MutationObserver(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 observer
setTimeout(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);
*/
//选择目标节点
var target=document.body,
定时器;
//创建一个观察者实例
var观察者=新的突变观察者(功能(突变){
//当突变发生时激发
定时器=设置超时(函数(){
控制台日志(“已执行”);
//我的程序();
}, 500);  
});
//观察员的配置:
var config={attributes:true,childList:true,characterData:true};
//传入目标节点以及观察者选项
observer.observe(目标,配置);
//测试我们的观察者
setTimeout(函数(){
document.body.innerHTML=“lol 1”;
document.body.innerHTML+=“lol 2”;
document.body.innerHTML+=“lol 3”;
}, 3000);
/*如果要添加更多div,请将其注释掉。。
setTimeout(函数(){
document.body.innerHTML+=“lol 4”;
document.body.innerHTML+=“lol 5”;
文件