chrome分机调用特定函数
chrome extension call specific function
我有一个popup.js:
function registerButtonAction(tabId, button, action) {
// clicking button will send a message to
// content script in the same tab as the popup
button.addEventListener('click', () => chrome.tabs.sendMessage(tabId, { [action]: true }));
}
function setupButtons(tabId) {
// add click actions to each 3 buttons
registerButtonAction(tabId, document.getElementById('start-btn'), 'startSearch');
registerButtonAction(tabId, document.getElementById('deals-btn'), 'startDeals');
}
function injectStartSearchScript() {
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
// Injects JavaScript code into a page
// chrome.tabs.executeScript(tabs[0].id, { file: 'main.js' });
// dd click handlers for buttons
setupButtons(tabs[0].id);
});
}
injectStartSearchScript()
// document.getElementById('inject-btn').addEventListener('click', injectStartSearchScript);
我用它来将我的脚本注入我的 popup.html 中带有“start-btn”的页面。
这是我的main.js,其中包含我想在页面上调用的函数:
function pong() {
// do something
}
function ping() {
// do something else
}
我的manifest.json:
{
"manifest_version": 2,
"name": "test app",
"description": "test desc",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": ["tabs", "<all_urls>"],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["main.js"]
}
]
}
所以基本上我的设置是我有一个 popup.html,其中包含 3 个按钮,它们应该调用我的 main.js 中的功能之一,具体取决于我按下的按钮。
但我无法让它工作。目前,如果我在加载时直接在 main.js 内调用 pong() ,我只能进行至少一个函数调用。但是我需要在单击 popup.html.
中的按钮后调用其中一个函数
编辑: 据我所知,我已经更新了代码。非常抱歉,但我不明白还需要更改哪些内容才能实现您的建议。我的意思是怎么写才更正确。
编辑 2: 我删除了行 chrome.tabs.executeScript(tabs[0].id, { file: 'main.js' });
以及 document.getElementById('inject-btn').addEventListener('click', injectStartSearchScript)
并添加了 injectStartSearchScript()
到 popup.js文件。你是这个意思吗?
带有解释的更新和完整示例(您快完成了!)
清单
您的清单看起来不错,无需更改。
此配置表示在每个选项卡中加载内容脚本。因此,甚至在弹出窗口打开之前,每个选项卡都会将“main.js”注入其中(恰好一次)。
popup.js
弹出脚本看起来不错,无需更改。
选项卡查找仍然是必要的,因为要将消息发送到特定选项卡,必须知道它的 ID。弹出窗口在当前 window 中查找当前活动的选项卡(与弹出窗口所在的相同)并设置按钮单击操作以向该选项卡发送消息。
main.js
此处需要进行小的改动
- 确保注册 onMessage listener,如下例所示。
- 注意条件:
message.startSearch
和 message.startDeals
-- 这些必须匹配从弹出窗口发送的消息,即当弹出窗口发送内容为 {startDeals: true}
的消息时,if 条件是startDeals
。它通过发送消息中的键匹配,如果键不匹配任何条件,消息将被忽略。
function pong() {
// do something
alert('Start!');
}
function ping() {
// do something else
alert('Deals!');
}
// register listener to receive messages
chrome.runtime.onMessage.addListener(message => {
// what to do on each received message:
if (message.startSearch) pong();
else if (message.startDeals) ping();
});
// sanity check: content has loaded in the tab
console.log('content loaded');
当内容脚本被配置为在清单中注入时,与调试扩展(可能是其中一些调试问题的来源)有关的另一个注意事项,Chrome 将注入 main.js 到标签中,在一个单独的扩展上下文中。如果在此注入后,开发人员重新加载扩展(chrome://extensions
或其他工具中的圆形箭头),这将使选项卡中内容脚本的上下文无效。必须重新加载该选项卡才能重新激活内容脚本。这不是真实用户的问题,但在调试过程中确实会发生,所以在调试时仔细检查这不是问题的原因。
我有一个popup.js:
function registerButtonAction(tabId, button, action) {
// clicking button will send a message to
// content script in the same tab as the popup
button.addEventListener('click', () => chrome.tabs.sendMessage(tabId, { [action]: true }));
}
function setupButtons(tabId) {
// add click actions to each 3 buttons
registerButtonAction(tabId, document.getElementById('start-btn'), 'startSearch');
registerButtonAction(tabId, document.getElementById('deals-btn'), 'startDeals');
}
function injectStartSearchScript() {
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
// Injects JavaScript code into a page
// chrome.tabs.executeScript(tabs[0].id, { file: 'main.js' });
// dd click handlers for buttons
setupButtons(tabs[0].id);
});
}
injectStartSearchScript()
// document.getElementById('inject-btn').addEventListener('click', injectStartSearchScript);
我用它来将我的脚本注入我的 popup.html 中带有“start-btn”的页面。
这是我的main.js,其中包含我想在页面上调用的函数:
function pong() {
// do something
}
function ping() {
// do something else
}
我的manifest.json:
{
"manifest_version": 2,
"name": "test app",
"description": "test desc",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": ["tabs", "<all_urls>"],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["main.js"]
}
]
}
所以基本上我的设置是我有一个 popup.html,其中包含 3 个按钮,它们应该调用我的 main.js 中的功能之一,具体取决于我按下的按钮。
但我无法让它工作。目前,如果我在加载时直接在 main.js 内调用 pong() ,我只能进行至少一个函数调用。但是我需要在单击 popup.html.
中的按钮后调用其中一个函数编辑: 据我所知,我已经更新了代码。非常抱歉,但我不明白还需要更改哪些内容才能实现您的建议。我的意思是怎么写才更正确。
编辑 2: 我删除了行 chrome.tabs.executeScript(tabs[0].id, { file: 'main.js' });
以及 document.getElementById('inject-btn').addEventListener('click', injectStartSearchScript)
并添加了 injectStartSearchScript()
到 popup.js文件。你是这个意思吗?
带有解释的更新和完整示例(您快完成了!)
清单
您的清单看起来不错,无需更改。
此配置表示在每个选项卡中加载内容脚本。因此,甚至在弹出窗口打开之前,每个选项卡都会将“main.js”注入其中(恰好一次)。
popup.js
弹出脚本看起来不错,无需更改。
选项卡查找仍然是必要的,因为要将消息发送到特定选项卡,必须知道它的 ID。弹出窗口在当前 window 中查找当前活动的选项卡(与弹出窗口所在的相同)并设置按钮单击操作以向该选项卡发送消息。
main.js
此处需要进行小的改动
- 确保注册 onMessage listener,如下例所示。
- 注意条件:
message.startSearch
和message.startDeals
-- 这些必须匹配从弹出窗口发送的消息,即当弹出窗口发送内容为{startDeals: true}
的消息时,if 条件是startDeals
。它通过发送消息中的键匹配,如果键不匹配任何条件,消息将被忽略。
function pong() {
// do something
alert('Start!');
}
function ping() {
// do something else
alert('Deals!');
}
// register listener to receive messages
chrome.runtime.onMessage.addListener(message => {
// what to do on each received message:
if (message.startSearch) pong();
else if (message.startDeals) ping();
});
// sanity check: content has loaded in the tab
console.log('content loaded');
当内容脚本被配置为在清单中注入时,与调试扩展(可能是其中一些调试问题的来源)有关的另一个注意事项,Chrome 将注入 main.js 到标签中,在一个单独的扩展上下文中。如果在此注入后,开发人员重新加载扩展(chrome://extensions
或其他工具中的圆形箭头),这将使选项卡中内容脚本的上下文无效。必须重新加载该选项卡才能重新激活内容脚本。这不是真实用户的问题,但在调试过程中确实会发生,所以在调试时仔细检查这不是问题的原因。