gpt4 book ai didi

javascript - 通过内容脚本设置的间隔被网页清除

转载 作者:行者123 更新时间:2023-11-30 17:03:03 25 4
gpt4 key购买 nike

在我的 chrome 扩展程序中,我在内容脚本中有一个 setInterval,它每 3 秒检查一次网页更改。

setInterval(detectChange, 3000)

function detectChange(){
...
}

除了一个网站 ( www.rdio.com ),这对所有网站都非常有效。网页脚本以某种方式清除了通过内容脚本设置的间隔。

我想到将 setInterval 放在后台脚本中,并在每个时间间隔向内容脚本发送一条消息。但这需要我跟踪运行内容脚本的所有选项卡,这似乎不是一个好主意。

如果有办法,请告诉我。

最佳答案

可取消的任务调度程序( setTimeoutsetIntervalrequestAnimationFrame 等)显然与文档相关联。尽管内容脚本的脚本执行上下文与页面是隔离的,但文档却不是。

站点清除并非由站点本身创建的计时器似乎很奇怪。您可以尝试调试问题,并通过覆盖 clearTimeout 检查站点为何完全清除计时器/clearInterval方法。

下面是一个示例,用于捕获清除不是由脚本本身安装的计时器的代码:

// Run this content script at document_start
var s = document.createElement('script');
s.textContent = '(' + function() {
var clearTimeout = window.clearTimeout;
var setTimeout = window.setTimeout;
var setInterval = window.setInterval;
// NOTE: This list of handles is NEVER cleared, because it is the
// only way to keep track of the complete history of timers.
var handles = [];
window.setTimeout = function() {
var handle = setTimeout.apply(this, arguments);
if (handle) handles.push(handle);
return handle;
};
window.setInterval = function() {
var handle = setInterval.apply(this, arguments);
if (handle) handles.push(handle);
return handle;
};
window.clearTimeout = window.clearInterval = function(handle) {
clearTimeout(handle);
if (handle && handles.indexOf(handle) === -1) {
// Print a stack trace for debugging
console.trace('Cleared non-owned timer!');
// Or trigger a breakpoint so you can follow the call
// stack to identify which caller is responsible for
// clearing unknown timers.
debugger;
}
};
} + ')();';
(document.head || document.documentElement).appendChild(s);
s.remove();

如果这表明该站点存在错误,并且(例如)清除了每个偶数编号的计时器,那么您只需调用 setTimeout 两次即可解决问题。

例如:

Promise.race([
new Promise(function(resolve) {
setTimeout(resolve, 3000);
}),
new Promise(function(resolve) {
setTimeout(resolve, 3000);
});
}).then(function() {
// Any of the timers have fired
});

如果一切都失败了......

如果发现站点以不可预知的方式清除计时器,您可以尝试使用其他异步方法或事件来安排任务,并测量调用之间的时间。当一定时间过去后,只需触发您的回调。例如,使用 requestAnimationFrame (通常称为每秒几次):

function scheduleTask(callback, timeout) {
timeout = +timeout || 0;
var start = performance.now();
function onDone(timestamp) {
if (timestamp - start >= timeout) callback();
else requestAnimationFrame(onDone);
}
requestAnimationFrame(onDone);
}

// Usage example:
console.time('testScheduler');
scheduleTask(function() {
console.timeEnd('testScheduler');
}, 1000);

或插入 <iframe>并在框架的上下文中创建计时器。

关于javascript - 通过内容脚本设置的间隔被网页清除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28516274/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com