Chrome扩展,javascript:为什么这是两次开火



我的(测试)Chrome扩展中有一段非常简单的代码:

    function test()
    {
    alert("In test!");
    }
   chrome.tabs.onUpdated.addListener(function(tabid, changeinfo, tab) {
    var url = tab.url;
        if (url !== undefined) {
        test();
    }
   });

我的问题是,为什么test()发射两次?更重要的是,我如何让它只火一次?

了解事件调度时的不同状态。我推测,当状态为"加载"或状态为"完成"时,它会被调度一次。如果是这样的话,那么你的问题就会用来解决

 function test()
    {
    alert("In test!");
    }
   chrome.tabs.onUpdated.addListener(function(tabid, changeinfo, tab) {
    var url = tab.url;
        if (url !== undefined && changeinfo.status == "complete") {
        test();
    }
   });

我也对此感到困惑,并试图找到答案。只有经过一些实验,我才明白为什么我收到了多个"完整"的更新事件,而我认为这是一个单独的页面"更新"。

如果你的页面有iframe,每个iframe都会触发一个"完整"事件,并冒泡到父内容脚本。因此,如果更复杂的页面有iframe,它们将触发大量onUpdated事件。

当您编写以下代码时:

chrome.tabs.onUpdated.addListener(function(tabid, changeinfo, tab) {
    var url = tab.url;
        if (url !== undefined) {
        test();
    }
});

您正在调用addListener,并告诉它不要立即调用test(),而是在更新选项卡时。选项卡更新事件由Chrome浏览器本身广播,这反过来又会导致test()代码运行。

我知道这是旧的,但无论如何。。。这也发生在我身上,也许这能帮助到别人。查看处理程序函数正在接收的Tab对象,我发现favIconUrl属性在两个调用中都不同,所以我想这与此有关,尽管我不知道这背后的原因。

我以为这是一个bug,但经过再三思考和一些测试,我放弃了bug理论。

到目前为止,我所知道的是,如果更改了两个属性,则事件会被触发两次,每次都包含一个属性的changeInfo对象。换句话说,例如,如果更改的属性是状态收藏夹URL,则

changeInfo = {status:"complete"};

然后在下一次呼叫

changeInfo = {favIconuUrl : ".... whatever ..."};

虽然我不确定为什么我们的代码会触发两次,但我也遇到了类似的问题,这个答案帮了我很多忙。

https://stackoverflow.com/a/49307437/15238857Vaibhav的回答非常聪明,以请求的细节对象的形式结合了验证。在记录details对象时,我注意到一种趋势,即最初的激发的frameId为0,而第二次激发总是其他的。因此,当你有重复的条目时,我喜欢使用if语句来返回并退出,而不是肯定地验证你是否正确提交了URL。我在这里使用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;
});

我通过在更新时检查选项卡的标题来解决这个问题:

chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
var title = changeInfo.title;
    if (title !== undefined) {
       doSomething();
    }
});

两次是由于状态加载一次,状态完成一次。如果您不关心状态,也可以尝试onCreated事件。那只会被炒一次!

最新更新