Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google chrome extension Chrome扩展后台页面以编程方式注入的内容脚本被多次注入_Google Chrome Extension - Fatal编程技术网

Google chrome extension Chrome扩展后台页面以编程方式注入的内容脚本被多次注入

Google chrome extension Chrome扩展后台页面以编程方式注入的内容脚本被多次注入,google-chrome-extension,Google Chrome Extension,我有一个chrome扩展,比如它将内容脚本a.js注入到匹配“*”的URL中。然后,当我单击example.com页面中的一些页面元素时,a.js会要求background使用定义的url创建一个新选项卡,并通过编程将内容脚本b.js插入到新选项卡中,您可以向下查看代码: chrome.tabs.create({ url: 'http://example.com' }, function (tab) { var taskTab = tab.id; chrome.tabs

我有一个chrome扩展,比如它将内容脚本a.js注入到匹配“*”的URL中。然后,当我单击example.com页面中的一些页面元素时,a.js会要求background使用定义的url创建一个新选项卡,并通过编程将内容脚本b.js插入到新选项卡中,您可以向下查看代码:


chrome.tabs.create({
    url: 'http://example.com'
}, function (tab) {
    var taskTab = tab.id;
    chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
        if (tabId === taskTab) {
            chrome.tabs.executeScript(taskTab, {
                file: 'scripts/b.js'
            });
        }
    });
});
问题是,内容脚本b.js会被注入新选项卡很多次。我也试过了,结果是一样的

那么如果我想让b.js只被注入新标签一次?我怎样才能做到

顺便说一句,b.js实际上是一个远程文件,我通过jQuery将其加载到页面中,这里为了简化问题,我将其设置为本地文件

非常感谢

更新 我必须弄清楚我的代码是怎么回事

首先,我将
onUpdated
事件侦听器包装在
create
回调中是错误的,每次我创建一个新选项卡,关闭它,再次创建它,事件侦听器都会再次绑定。越多越好

其次,@Xan是对的,我可以通过检查
changeInfo.status
来完成。因此,代码应该是:


var taskTab;
chrome.tabs.create({
    url: 'http://example.com'
}, function (tab) {
    taskTab = tab.id;
});
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
  if (changeInfo.status === 'complete'){
    if (tabId === taskTab) {
       chrome.tabs.executeScript(taskTab, {
            file: 'scripts/b.js'
        });
    }
  }
});
而b.js只会被注入一次,不管它是本地文件还是jQuery加载的远程文件

  • onUpdate
    事件可能会触发,原因有很多:

    对象更改信息

    列出对已更新选项卡状态的更改

    字符串(可选)状态
    :选项卡的状态。可以是加载或完成

    字符串(可选)url
    :选项卡的url(如果已更改)

    布尔(可选)锁定
    :选项卡的新锁定状态

    string(可选)favIconUrl
    :选项卡的新favicon URL

    您可能希望通过
    changeInfo

  • 故障保护方法:当您注入第二个脚本时,在执行脚本的其余部分之前,设置一些检查
    undefined
    的保护变量。任何其他注入脚本的尝试都将在相同的上下文中,并将看到变量集。有点像C的
    #ifndef
    包含


  • 你试过用
    b.js
    作为本地文件运行它来重现错误吗?@NimaVaziri,是的,它可以重现。1。我还尝试了changeInfo status,没有“加载”或“完成”的运气,似乎连
    onUpdated
    事件下的状态都会发生很多次。2.我确实有一些保护方法来防止多次执行内容脚本,但扩展多次将内容脚本注入新选项卡仍然毫无意义。我们只期望它一次,不多。@chenxsan我不明白,为什么你要在
    onUpdated
    中注入,而不是在
    create
    回调中注入?如果我在
    create
    回调中注入,代码(它会在
    主体
    标记中附加一些html代码)有时会不起作用。所以我必须在更新的
    内部注入
    ,这是一种变通方法。@chenxsan这是一种糟糕的变通方法。考虑您可以在<代码>执行文件Script < /代码>中指定<代码> RunAT:“Debug”。如果这也不起作用,请考虑在一个特定的DOM事件中,将侦听的代码包在一个特定的DOM事件中,然后再注入。默认值为<代码> RunAT< <代码> > ExtUpScript Script < /Cord>,我已经尝试了所有其他的值,如:代码>文档>结束/代码>等等。这真的很烦人,但我想我会试试的。