javascript Chrome 扩展:创建新标签(chrome.tabs.create)并在新标签中执行脚本......不工作:(
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16862479/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Chrome Extension: create new tab(chrome.tabs.create) and executeScript in new tab...not working :(
提问by user2441282
I'm currently working on a Google Chrome extension that will allow a Pinterest user to easily pin multiple images from a page (a functionality that is currently not available). To achieve this, the extension has a background page and two content scripts (contentScript1.js and contentScript2.js). For clarities sake I'll explain what my extension is supposed to do, and then elaborate on what problem is arising. My extension's (simplified) order of events goes like this:
我目前正在开发一个 Google Chrome 扩展程序,该扩展程序将允许 Pinterest 用户轻松地从一个页面固定多个图像(该功能目前不可用)。为了实现这一点,扩展有一个背景页面和两个内容脚本(contentScript1.js 和 contentScript2.js)。为了清楚起见,我将解释我的扩展程序应该做什么,然后详细说明出现了什么问题。我的扩展程序的(简化的)事件顺序是这样的:
- A user is surfing the Web, and decides they want to pin an image from the current tab, so they click my extension's browser button!
- When the browser button is clicked, the background.js file fires a message to contentScript1.js to say “hey, grab every img tag on this page and allow for the user can select ‘em”
- contentScript1.js receives the message from background.js, which invokes a function that grabs all images and appends a submit button to the page
- The user clicks the images they want, and then clicks the submit button
- When the submit button is clicked, contentScript1.js fires a message to background.js
- When background.js receives the message from contentScript1.js, it redirects the user to pinterest.com to allow for pinning. *Note: when the tab is created with a url of pinterest.com, pinterest.com is now the active tab (a chrome extension default of chrome.tabs.create),
- After background.js creates the new tab, it executes contentScript2.js in the current tab, which is now pinterest.com
- 用户正在网上冲浪,并决定从当前选项卡固定图像,因此他们单击我的扩展程序的浏览器按钮!
- 当点击浏览器按钮时,background.js 文件会向 contentScript1.js 发送一条消息说“嘿,抓住这个页面上的每个 img 标签并允许用户选择它们”
- contentScript1.js 从 background.js 接收消息,它调用一个函数来抓取所有图像并将提交按钮附加到页面
- 用户点击自己想要的图片,然后点击提交按钮
- 单击提交按钮时,contentScript1.js 会向 background.js 发送一条消息
- 当 background.js 收到来自 contentScript1.js 的消息时,它会将用户重定向到 pinterest.com 以允许固定。*注意:当使用 pinterest.com 的 url 创建选项卡时,pinterest.com 现在是活动选项卡(chrome.tabs.create 的 chrome 扩展默认值),
- background.js 创建新标签后,在当前标签中执行 contentScript2.js,现在是 pinterest.com
Okay, everything works fine-and-dandy except contentScript2.js is executed in ANY CURRENT TAB. So more specifically, if I opened up my browser right now, my tester function that is in contentScript2.js will be executed. However, my pinterest.com tab is only created at the appropriate time (when the submit button is clicked). From my understanding, I shouldn't need to use message passing between background.js and contentScript2.js, because of the default settings of chrome.tabs.create. Nonetheless, I tried using message passing and it still didn't work ?
好的,除了 contentScript2.js 在任何当前选项卡中执行之外,一切都运行良好。更具体地说,如果我现在打开浏览器,将执行 contentScript2.js 中的 tester 函数。但是,我的 pinterest.com 选项卡仅在适当的时间(单击提交按钮时)创建。根据我的理解,由于 chrome.tabs.create 的默认设置,我不需要在 background.js 和 contentScript2.js 之间使用消息传递。尽管如此,我尝试使用消息传递,但仍然无效?
Here's the code:
这是代码:
manifest.json:
{
"manifest_version" : 2,
"name" : "Pin 'em",
"description" : "Pin multiple images to different Pinterest boards in just two clicks",
"version" : "1.1",
"permissions" : [
"tabs",
"<all_urls>"
],
"browser_action" : {
"default_icon" : "images/icon.png"
},
"background" : {
"page" : "background.html",
"persistent" : false
},
"content_scripts" : [
{
"matches" : ["<all_urls>"],
"js" : ["lib/jquery.min.js", "src/contentScript1.js", "src/contentScript2.js"],
"css" : ["stylesheets/style.css"]
}
]
}
and the background page:
和背景页面:
background.js
//when browser icon is clicked, current tab is selected
//sends message to contentScript1.js
chrome.browserAction.onClicked.addListener(function() {
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.sendMessage(tab.id, 'displayImages');
});
});
//when message 'redirectImages' is received
//a new tab is created (url = http://pinterest.com)
//extension executes contentScript2.js in pinterest.com
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
if (request.action === 'redirectImages') {
sendResponse({received : 'success'});
injectScript();
}
});
function injectScript() {
chrome.tabs.create({url : 'http://pinterest.com'}, function(tab) {
chrome.tabs.executeScript(tab.id, {file: 'src/contentScript2'});
});
};
first content script:
第一个内容脚本:
contentScript1.js
function sendMess() {
chrome.extension.sendMessage({action : 'redirectImages'}, function(response) {
success = response.received;
console.log(success);
});
};
function appendImages() {
//...does stuff to make a pretty overlay and
//...grabs img tags, and displays for user to select to select
//...appends a submit button with class='submit-images'
};
$(document).on('click', '#submit-images', function(e) {
//..does magic that you need not worry about (i think?)
sendMess();
});
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
if (request === "displayImages") {
appendImages();
}
});
second content script
第二个内容脚本
contentScript2.js
function tester() {
console.log('pinterest script injected');
};
var tester = tester();
采纳答案by apsillers
contentScript2.js
is executed in ANY CURRENT TAB
contentScript2.js
在任何当前选项卡中执行
That's because, in your manifest, you've included it in your content_scripts
that load on <all_urls>
. It seems like you want to programmatically decide when to run the script, which is exactly what executeScript
is used for.
那是因为,在您的清单中,您已将其包含content_scripts
在<all_urls>
. 似乎您想以编程方式决定何时运行脚本,这正是executeScript
用于的目的。
Simply remove contentScript2.js
from your manifest, and executeScript
will do the injection as you expect.
只需contentScript2.js
从您的清单中删除,executeScript
就会按照您的预期进行注入。