setTimeout持续触发
setTimeout keeps firing
我有一个简单的chrome扩展,它与页面的DOM一起工作(它寻找"某些东西"看起来像登录表单)。问题是,许多页面都有"动态"登录表单——它的代码是在需要时加载的。这就是为什么body的onload事件是不够的。
因此,我创建了突变观察者,并在每次DOM更改时执行我的过程(将来会有一些限制-许多这些更改不会影响我的目的)
由于某些间隔,我必须在更新的DOM上实现延迟执行过程(时间500仅用于测试目的)
var target = document.body;
var timer;
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
var count = mutation.addedNodes.length;
if( count > 0) {
timer = setTimeout(function (){
console.log("executed");
my_procedure();
}, 500);
}
});
});
var config = { attributes: true, childList: true, characterData: true };
observer.observe(target, config);
问题是,setTimeout一直触发到无穷大,这使得页面在一段时间后非常懒惰。在Chrome JS控制台'已执行'消息的数量仍在增加。
我知道clearTimeout(timer)
,但我不能正确使用它-所以my_procedure
只在每次DOM更改时执行一次。
编辑:my_procedure
实际上是第三方库函数,所以我不想(或可以)改变它-函数开始整个形式分类逻辑。
谢谢你的建议。
在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);
为什么setTimeout
似乎火无限的原因是,它实际上火灾有许多次,例如,新的元素添加到DOM。所以基本上,如果3div被添加到DOM,它会分配3个setTimeout
调用。原因是,你是在mutations.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,它也应该在控制台显示一次"已执行"。
js提琴示例
代码:
// 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 var "定时器",然后你使用".forEach()"对你的"突变" !
所以你每次都覆盖计时器,这就是为什么如果你在my_procedure中设置clearTimeout它不起作用(它只会停止1个计时器,最后一个突变)。
- setInteval vs setTimeout
- 如何在chrome扩展中存储数据/结果,以及如何使用setTimeout使其只被调用一次
- setTimeout可以与闭包内的函数一起使用吗
- Javascript setTimeout for an array
- 刷新后,setTimeout将工作或不工作
- 继续使用javascript中的setTimeout
- setTimeout函数能否在其前面的代码执行之前激发
- jQuery setTimeOut: in for-loop
- SetTimeout and clearTimeout in Javascript
- 在setTimeout中调用相同的函数
- setTimeout不能太长
- Javascript-SetTimeout导致浏览器冻结
- setTimeout and V8
- 将jQuery对象传递到setTimeout递归函数中
- 是定义的操作系统睡眠/挂起期间setTimeout的行为
- 添加一个setTimeout方法会使jQuery悬停方法忽略setTimeout方法中的函数
- JS:setTimeout函数的UI计数
- 使setInterval和setTimeout工作时出现问题
- 为什么setTimeout适用于无休止的递归调用
- settimeout调用的函数未结束