我希望我的Chrome扩展程序能够像这样运行:
用户点击图标并显示硬编码的网址“www.example.com”。它不会打开新选项卡,而是更新窗口。然后,我想执行内容脚本,并能够在更新的页面上提醒“工作”。
这是我到目前为止所得到的:
Background.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运行正常,但有时警报会起作用,有时则不会。即使是更奇怪,如果我双击它会更频繁地工作,但是如果我多次点击它,警报会加起来,然后我会同时收到很多警报(我只想要一个)。
答案 0 :(得分:3)
content.js 可以设置一个全局变量,以便您可以检查它以跳过重新注入。
if (window[chrome.runtime.id]) {
alert('Oi! Reinjected.');
} else {
window[chrome.runtime.id] = true;
alert('Oi!');
}
// do something
根据您在内容脚本中执行的操作,您可以添加message listener来处理来自后台页面的请求,而不是重新运行整个代码。
background.js 检查活动标签是否已导航到感兴趣的网站(或导航到该网站)并注入内容脚本(注释掉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>
这样的较大权限会包含这些权限,但确切列表的优势在于,扩展程序网络商店中的安装警告将仅显示该网站。
*
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/*"]
}