Chrome扩展程序,javascript:为什么这次解雇两次?

时间:2011-05-29 14:00:26

标签: javascript google-chrome google-chrome-extension

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

    function test()
    {
    alert("In test!");
    }

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

        test();
    }
   });

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

7 个答案:

答案 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事件。这只会被解雇一次!