【问题标题】:chrome.tabs.onUpdated.addListener() is called twicechrome.tabs.onUpdated.addListener() 被调用两次
【发布时间】:2015-12-06 09:19:28
【问题描述】:

我正在编写一个 chrome 扩展程序,并且在某些网站上 chrome.tabs.onUpdated.addListener() 被调用了两次。

这主要发生在我点击链接而不是我自己输入 URL 时。

根据我在网上找到的信息以及在 StackOverflow 上提出的许多问题,chrome 上存在一个错误,但几年前已修复。

有些人声称如果页面中有多个 iframe,就会发生这种情况,但在我的情况下,我的页面中没有 iframe。

这是我的代码:

 var storage = chrome.storage.local;

chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
    if (changeInfo.status == 'complete' && tab.status == 'complete' && tab.url != undefined) {
            storage.get('URLs', function(URLs){
                for (var item in URLs)
                {
                    if (tab.url == item)
                    {
                        return;
                    }
                    else
                    {
                        //alert ("tab load complete");
                        storage.set({URLs: [tab.url]});
                        chrome.tabs.executeScript(tab.id, {
                        "file": "flashblocker.js"
                        }, function () { // Execute your code
                        console.log("Script Executed .. "); // Notification on Completion
                        });
                    }
                }
            });
    }
});

如何让它只运行一次?

谢谢。

【问题讨论】:

  • onUpdated 可以在调用历史 API 时调用,或者只是 '#foo' 哈希值改变。我认为您需要在下面使用@Nikhil 的方法。

标签: google-chrome google-chrome-extension


【解决方案1】:

使用变量并在侦听器中添加检查,以在执行警报之前检查此变量的值。你可以这样做:

var tabUpdated = false;
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
    if (changeInfo.status == 'complete' && tab.status == 'complete' && tab.url != undefined) {
        if (!tabUpdated) {
            alert("tab load complete");
            tabUpdated = true;
        }
    }
});

但是如果内容脚本实际上加载了两次,这将失败,因为 tabUpdated 变量将再次被初始化为 false。在这种情况下,您可以使用 chrome 的 Storage API 并存储已调用侦听器的 URL。只需为此添加一个检查,如果 URL 存在存储中,则不会调用警报,否则它将调用。然后,您可以在浏览器启动或关闭时清除存储。

chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
    if (changeInfo.status == 'complete' && tab.status == 'complete' && tab.url != undefined) {
        chrome.local.storage.get('URLs', function(URL's) {
            // Iterate through this list here and match with tab.url, if the match is found, just return.
            if (url is there in list) {return;}
            else {
                alert("tab load complete");
                chrome.local.set({URLs: [tab.url]}); 
            }
        });
    }
});

这只是您如何实现它的一个示例。根据您的需要进行调整。

我希望这会有所帮助。

【讨论】:

  • Nikhil 感谢您的评论。它适用于 alert("") 但问题是我正在尝试运行一个脚本(我已经用代码更新了我的答案)并且脚本仍然运行了两次。有什么想法吗?
  • 是的,因为您正在用新 URL 替换旧 URL。只需将新 URL 添加到旧 URL 数组,然后使用 storage.set() 保存。首先将使用 storage,get() 获得的 URL 存储到变量中,然后在 else 块中将新 URL 添加到该数组,然后保存。对不起,我忘了在我的答案中添加代码。就这样试试吧。我希望这会有所帮助。
  • 另外,只需使用一个变量来存储是否找到匹配项的结果,然后将此变量用于for loop 之外的 if else 块。使用中断而不是返回。你能想到为什么不应该在循环内检查它..??
  • 我是 JS 新手,不知道为什么不在循环中执行此操作。现在我正在尝试了解如何将 tab.url 添加到 URL 列表中:) 为什么要在循环内完成?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-01
  • 2012-05-05
  • 2017-01-19
  • 2014-02-04
  • 2016-12-13
  • 2016-01-30
  • 2015-12-20
相关资源
最近更新 更多