简体   繁体   English

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

[英]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.jsmodal.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.jsmodal.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.jsmodal.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.

相关问题 从chrome扩展的内容脚本动态注入jQuery后,为什么不能使用jQuery? - Why can't I use jQuery after it's dynamically injected from a chrome extension's content-script? 无法使用jQuery访问通过Google Chrome内容脚本注入的iframe的内容 - can't access content of iframe injected via google chrome content script using jquery jQuery还记得是否已经注入了脚本吗? - jQuery remembering if a script was already injected? Background.js找不到使用内容脚本注入的内容 - Background.js Doesn't Find Content Injected with Content Script 内容脚本被注入每一帧,但似乎没有执行 - Content Script is injected in every frame but doesn't seem to execute 通过响应从注入的脚本到内容脚本的通信 - Communication from an injected script to the content script with a response 无法在我的脚本上清除Interval,但为什么呢? - can't clearInterval on my script, but why? 如何将数据从注入的内容脚本传递到iframe? - How can I pass data from an injected content script to an iframe? 为什么在jsonp请求中看不到jquery注入的脚本标签? - why can't I see the script tag injected by jquery in jsonp request? 为什么我的 chrome 扩展内容脚本无法访问页面元素的属性? - Why can't my chrome extension content script have access to a page element's property?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM