javascript - 为什么我的内容脚本不能使用已经注入(inject)的脚本?

标签 javascript google-chrome-extension

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

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

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

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

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);
});

我的问题是,如果我已经在页面加载后注入(inject)了 modal.jsmodal.css,为什么我需要再次注入(inject)这些文件加载模态?每当用户单击页面上的链接时,我的扩展程序都会加载模式。所以我担心的是,如果我必须在用户单击某些内容时将这两个文件注入(inject) 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);
    });
});

最佳答案

实际上我很惊讶调用 injectStuffs()第二次有效!我认为问题是由您的内容脚本运行的“孤立世界”引起的:

Content scripts execute in a special environment called an isolated world. They have access to the DOM of the page they are injected into, but not to any JavaScript variables or functions created by the page. It looks to each content script as if there is no other JavaScript executing on the page it is running on. [reference]

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

相比之下,当您通过编写 <script> 来注入(inject) JavaScript 文件时DOM 元素,这些文件被认为是页面的一部分,因此您的内容脚本看不到其中定义的函数/变量。

所以在你的情况下,content.js 在你的内容脚本中,但是 jquery-1.11.3.min.jsmodal.js 在页面中。这就是 content.js 无法调用 loadModal() 的原因.

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

关于javascript - 为什么我的内容脚本不能使用已经注入(inject)的脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33642035/

相关文章:

javascript - 将新键/值对添加到 chrome.storage.sync 中的现有键

google-chrome - 如何使用 Chrome 扩展内容脚本匹配具有相同域的多个网站

javascript - 检查 JS 是否可以访问 iframe 的文档

javascript - 如何在 GridView 的 OnLoad 事件上调用 javascript 函数?

javascript - 首先执行代码的错误部分

javascript - Chrome 扩展程序将变量从 popup.js 传递到内容脚本

javascript - 从扩展访问 document.activeElement.value

javascript - 在 javascript 被阻止时保持 google chrome 扩展 ContentScripts 正常工作

javascript - 如何在子函数中引用父对象?

javascript - AngularJS 搜索并显示更多结果