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