为什么我的内容脚本不能使用已注入的脚本?

时间:2015-11-11 00:07:37

标签: javascript google-chrome-extension

对于我的Chrome扩展程序,我使用content.js注入了模式加载所需的Javascript文件和CSS文件。注入成功,我在DOM中看到了这两个文件。

然后我发送消息到background.js做一些事情,这也有效,因为我从那里收到消息。但是我的模态无法加载,因为它似乎无法使用注入的Javascript文件。

假设我有一个将文件注入DOM的函数。我们称之为inject()。我在content.js文件的开头调用此函数并成功注入它们。但是当我从background.js收到消息并尝试加载模态时,它会失败。

如果我再次尝试在inject()函数内调用chrome.runtime.sendMessage函数,则模态成功加载。

content.js我有以下代码。每当用户点击当前页面上的链接时,我都会向后台脚本发送一条消息。

chrome.runtime.sendMessage(link,function(response){
     inject(); //Now the modal loads. But if I remove this, the modal fails to load.    
     loadModalFunction(response);
});

我的问题是,如果我在页面加载后已经注入modal.jsmodal.css,为什么我需要再次注入文件来加载模态?每当用户单击页面上的链接时,我的扩展程序都会加载模态。所以我担心的是,如果每当用户点击某些内容时我必须将两个文件注入DOM,这会使页面变慢。

使用更多代码进行更新:

content.js

function injectStuffs(){
    var jquery = chrome.extension.getURL("jquery-1.11.3.min.js");
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = jquery;
    $("head").append(script);

    var modaljs = chrome.extension.getURL("modal.js");
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = modaljs;
    $("head").append(script);

    var link = document.createElement("link");
    link.href = chrome.extension.getURL("modal.css");
    link.type = "text/css";
    link.rel = "stylesheet";
    $("head").append(link); 
}

injectStuffs() //Inject the scripts into ```DOM```

$(document).on('click', '.readmore a', function(event) {
    event.preventDefault();
    var link = $(this).attr('href');

    chrome.runtime.sendMessage(link,function(response){
        injectStuffs() //I need to inject here again to load the modal up. Why?
        loadModal(response);
    });
});

1 个答案:

答案 0 :(得分:1)

我真的很惊讶第二次打电话injectStuffs()有效!我认为这个问题是由孤立的世界引起的。您的内容脚本正在运行:

  

内容脚本在称为孤立世界的特殊环境中执行。他们可以访问注入页面的DOM,但不能访问页面创建的任何JavaScript变量或函数。它将每个内容脚本视为在其运行的页面上没有执行其他JavaScript。 [reference]

当您在清单中的内容脚本的js属性中列出JavaScript文件时,所有这些文件都被视为内容脚本的一部分,因此每个文件都可以查看其他人定义的函数/变量(但不在页面中)。

相反,当您通过将<script>元素写入DOM来注入JavaScript文件时,这些文件被认为是页面的一部分,因此您的内容脚本无法使用查看其中定义的函数/变量。

因此,在您的情况下, content.js 位于您的内容脚本中,但 jquery-1.11.3.min.js modal.js 在页面中。这就是为什么 content.js 无法呼叫loadModal()

您可能希望将 jquery-1.11.3.min.js modal.js 添加到清单中的内容脚本中。但是,如果确实需要在运行时决定是否加载JavaScript文件,请参阅programmatic injection的文档。