我希望我的 Chrome 扩展程序像这样运行:
用户单击该图标,就会显示硬编码的 URL“www.example.com”。它不会打开新选项卡,而是更新窗口。然后我想执行内容脚本并能够在更新的页面上提醒“正在工作”。
这是我到目前为止所得到的:
背景.js
chrome.browserAction.onClicked.addListener(function(activeTab)
{
chrome.tabs.query({'active': true, 'lastFocusedWindow': true}, function
(tabs)
{
chrome.tabs.update({
url: "http://www.example.com/"
});
});
function test()
{
chrome.tabs.executeScript(null, {file: "myscript.js"});
}
chrome.tabs.onUpdated.addListener(function(tabid, changeinfo, tab) {
var url = tab.url;
if (url !== undefined && changeinfo.status == "complete") {
test();
}
});
});
内容脚本
alert('working');
结果很奇怪。当我单击该图标时,它会很好地显示 example.com,但有时警报有效,有时则无效。更奇怪的是,如果我双击它,它会更频繁地工作,但如果我点击它很多次,警报就会累加起来,然后我会立即收到许多警报(我只想要一个)。
最佳答案
content.js 可以设置全局变量,以便您可以检查它以跳过重新注入(inject)。
if (window[chrome.runtime.id]) { alert('Oi! Reinjected.'); } else { window[chrome.runtime.id] = true; alert('Oi!'); } // do something
根据您在内容脚本中执行的操作,您可以添加 message listener它将处理来自后台页面的请求,而不是重新运行整个代码。
background.js 检查事件选项卡是否已导航到感兴趣的网站(或导航到它)并注入(inject)内容脚本(注释掉
inject();
以跳过重新注入(inject)) .检查本身很简单:注入(inject)检查该全局变量的内容脚本代码。此代码与给定页面的其他内容脚本在相同的上下文中运行( isolated world )。
const SITE_URL = 'http://www.example.com'; chrome.browserAction.onClicked.addListener(tab => { if (tab.url === new URL(SITE_URL).href) { checkIfInjected(tab).then(tab => { console.log('already injected in %d, reinjecting anyway', tab.id); inject(tab); }).catch(inject); } else { updateTabAndWaitForStart(tab.id, {url: SITE_URL}) .then(inject); } }); function checkIfInjected(tab) { return runContentScript(tab.id, { code: 'window[chrome.runtime.id]', }).then(results => { resolve(results[0] ? tab : Promise.reject(tab)); }); } function inject(tab) { return runContentScript(tab.id, { file: 'content.js', runAt: 'document_end', allFrames: false, }); } function runContentScript(tabId, options) { return new Promise(resolve => { chrome.tabs.executeScript(tabId, options, resolve); }); }
// onUpdated listener waits for our tab to get an URL, detaches on success
function updateTabAndWaitForStart(tabId, options) { return new Promise(resolve => { chrome.tabs.update(tabId, options, newTab => { chrome.tabs.onUpdated.addListener( function onUpdated(updatedId, info, updatedTab) { if (updatedId === newTab.id && info.url) { chrome.tabs.onUpdated.removeListener(onUpdated); resolve(updatedTab); } } ); }); }); }
manifest.json 应包含您导航到的网站和事件选项卡的权限。
当然,更大的权限,如
<all_urls>
将包括这些,但精确列表的优点是扩展 Web 商店中的安装警告将仅显示该网站。*
站点 URL 中的权限是可选的(与 API 设计的工作方式相同)。
决赛/
是强制性的(它是一条路径)。{ "name": "test", "version": "0.0.1", "manifest_version": 2, "description": ".............", "background": { "scripts": ["background.js"], "persistent": false }, "browser_action": { "default_title": "click me" }, "permissions": ["activeTab", "http://www.example.com/*"] }
关于javascript - 如何使用Background.js更新选项卡然后执行内容脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45857346/