我的(测试)Chrome扩展程序中有一个非常简单的代码:
function test()
{
alert("In test!");
}
chrome.tabs.onUpdated.addListener(function(tabid, changeinfo, tab) {
var url = tab.url;
if (url !== undefined) {
test();
}
});
我的问题是,为什么test()
两次开火?更重要的是,我该如何让它只开一次?
答案 0 :(得分:30)
查看调度事件时的不同状态。我认为,当状态为“加载”或状态为“完成”时,它将被调度一次。如果是这种情况,那么您的问题将通过以下方式解决:
function test()
{
alert("In test!");
}
chrome.tabs.onUpdated.addListener(function(tabid, changeinfo, tab) {
var url = tab.url;
if (url !== undefined && changeinfo.status == "complete") {
test();
}
});
答案 1 :(得分:5)
我也对此感到困惑并试图找到答案。只有经过一些实验,我才弄清楚为什么我收到了多个“完整”更新事件,因为我认为这是一个单页“更新”。
如果您的网页包含iframe,则每个网页都会触发“完整”事件并冒泡到父内容脚本。因此,如果更复杂的页面有iframe,则会触发大量的onUpdated事件。
答案 2 :(得分:2)
编写以下代码时:
chrome.tabs.onUpdated.addListener(function(tabid, changeinfo, tab) {
var url = tab.url;
if (url !== undefined) {
test();
}
});
您正在致电addListener
并告诉其不要立即致电test()
,而是在更新标签时 。标签更新事件由Chrome浏览器本身广播,这反过来会导致您的test()
代码运行。
答案 3 :(得分:2)
我知道这已经过时了但无论如何......它也发生在我身上,也许这可以帮助别人。查看处理程序函数正在接收的Tab对象,我看到 favIconUrl 属性在两个调用中都不同,所以我猜它与此有关,尽管我不知道这背后的原因
我认为这是一个错误,但在经过第二次思考和一些测试后,我放弃了错误理论。
到目前为止我所知道的是,如果更改了两个属性,则每次使用包含一个属性的 changeInfo 对象触发事件两次。换句话说,如果更改的属性是 status 和 favIconUrl ,那么
changeInfo = {status:"complete"};
然后在下次通话中
changeInfo = {favIconuUrl : ".... whatever ..."};
答案 4 :(得分:1)
虽然我不确定为什么我们的代码会触发两次,但我遇到了类似的问题,这个答案对我帮助很大。
https://stackoverflow.com/a/49307437/15238857 Vaibhav 的回答在以请求的详细信息对象的形式合并验证方面非常聪明。 在记录详细信息对象时,我注意到原始触发的 frameId 为 0 的趋势,而第二次触发总是其他内容。因此,与其积极验证您是否正确提交了 URL,我喜欢使用 if 语句在您有重复条目时返回并退出。 我在这里使用 onCompleted,但它也适用于 onUpdated。
chrome.webNavigation.onCompleted.addListener(details => {
//need to make sure that this only triggers once per navigation
console.log(details);
if (details.frameId !== 0) return;
});
答案 5 :(得分:0)
我通过在更新时检查标签的标题解决了这个问题:
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
var title = changeInfo.title;
if (title !== undefined) {
doSomething();
}
});
答案 6 :(得分:-1)
两次是由于状态正在加载一次而状态完成一次。 如果你不关心状态,你也可以尝试onCreated事件。这只会被解雇一次!