[英]Why can't my content script use already injected script?
For my Chrome extension, I inject a Javascript file and a CSS file that are needed for the modal to load up by using content.js
.对于我的 Chrome 扩展程序,我注入了一个 Javascript 文件和一个 CSS 文件,这些文件是使用content.js
加载模态所需的。 Injection is successful and I see those two files in the DOM.注入成功,我在 DOM 中看到了这两个文件。
And then I send a message to the background.js
to do some stuff and this works too because I receive the message back from there.然后我向background.js
发送一条消息来做一些事情,这也有效,因为我从那里收到了消息。 But my modal fails to load because it seems that it cannot use the injected Javascript file.但是我的模态无法加载,因为它似乎无法使用注入的 Javascript 文件。
Let's say I have a function that inject the files into DOM.假设我有一个将文件注入 DOM 的函数。 Let's call it inject()
.我们称它为inject()
。 I call this function at the start of the content.js
file and they are injected successfully.我在content.js
文件的开头调用了这个函数,并且它们被成功注入。 But when I get back message from background.js
and try to load the modal, it fails.但是当我从background.js
收到消息并尝试加载模态时,它失败了。
If I again try to call inject()
function inside chrome.runtime.sendMessage
function, the modal successful loads up.如果我再次尝试在chrome.runtime.sendMessage
函数中调用inject()
函数,模态成功加载。
In content.js
I have the following code.在content.js
我有以下代码。 I send a message to the background script whenever user click a link on the current page.每当用户单击当前页面上的链接时,我都会向后台脚本发送一条消息。
chrome.runtime.sendMessage(link,function(response){
inject(); //Now the modal loads. But if I remove this, the modal fails to load.
loadModalFunction(response);
});
My question then is if I had already injected modal.js
and modal.css
as soon as the page has loaded, why do I need to inject the files again to load the modal?我的问题是,如果我在页面加载后就已经注入了modal.js
和modal.css
,为什么我需要再次注入文件来加载模态? My extension loads the modal whenever a user click a link on a page.每当用户单击页面上的链接时,我的扩展程序都会加载模式。 So my concern is that if I have to inject the two files into the DOM whenever a user clicks something, it would make the page slow.所以我担心的是,如果我必须在用户单击某些内容时将这两个文件注入到 DOM 中,这会使页面变慢。
Update with more code:更新更多代码:
In content.js
:在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);
});
});
I'm actually surprised that calling injectStuffs()
a second time works!我真的很惊讶第二次调用injectStuffs()
有效! I believe the problem is caused by the "isolated world" that your content script is running in:我相信问题是由您的内容脚本运行的“孤立世界”引起的:
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.他们可以访问被注入页面的 DOM,但不能访问页面创建的任何 JavaScript 变量或函数。 It looks to each content script as if there is no other JavaScript executing on the page it is running on.它查看每个内容脚本,就好像它正在运行的页面上没有其他 JavaScript 正在执行一样。 [reference] [参考]
When you list JavaScript files in the js
property of a content script in your manifest, all those files are considered to be part of the content script , so each of the files can see the functions/variables defined in the others (but not in the page).当您在清单中的内容脚本的js
属性中列出 JavaScript 文件时,所有这些文件都被视为内容脚本的一部分,因此每个文件都可以看到其他文件中定义的函数/变量(但不能在页)。
In contrast, when you inject JavaScript files by writing <script>
elements to the DOM, those files are considered to be part of the page , so your content script can't see the functions/variables defined in them.相反,当您通过将<script>
元素写入 DOM 来注入 JavaScript 文件时,这些文件被视为页面的一部分,因此您的内容脚本无法看到其中定义的函数/变量。
So in your situation, content.js is in your content script, but jquery-1.11.3.min.js and modal.js are in the page.所以在你的情况下, content.js在你的内容脚本中,但jquery-1.11.3.min.js和modal.js在页面中。 That's why content.js can't call loadModal()
.这就是content.js不能调用loadModal()
。
You probably want to add jquery-1.11.3.min.js and modal.js to your content script in the manifest.您可能希望将jquery-1.11.3.min.js和modal.js添加到清单中的内容脚本中。 But if you really need to decide at runtime whether to load the JavaScript files, then see the docs for programmatic injection .但是,如果您确实需要在运行时决定是否加载 JavaScript 文件,请参阅编程注入文档。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.