Dyl*_*anP 0 javascript google-chrome-extension
我希望我的 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();
}
});
});
Run Code Online (Sandbox Code Playgroud)
内容脚本
alert('working');
Run Code Online (Sandbox Code Playgroud)
结果很奇怪。当我单击该图标时,它会很好地显示 example.com,但有时警报有效,有时则无效。更奇怪的是,如果我双击它,它会更频繁地工作,但如果我多次单击它,警报就会累加起来,然后我会立即收到许多警报(我只想要一个)。
content.js可以设置一个全局变量,以便您可以检查它以跳过重新注入。
if (window[chrome.runtime.id]) {
alert('Oi! Reinjected.');
} else {
window[chrome.runtime.id] = true;
alert('Oi!');
}
// do something
Run Code Online (Sandbox Code Playgroud)
根据您在内容脚本中执行的操作,您可以添加一个消息侦听器,它将处理来自后台页面的请求,而不是重新运行整个代码。
background.js检查活动选项卡是否已导航到感兴趣的站点(或导航到它)并注入内容脚本(注释掉inject();以跳过重新注入)。
检查本身很简单:注入检查该全局变量的内容脚本代码。此代码与给定页面(孤立的世界)的其他内容脚本在相同的上下文中运行。
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);
});
}
Run Code Online (Sandbox Code Playgroud)
// onUpdated listener waits for our tab to get an URL, detaches on success
Run Code Online (Sandbox Code Playgroud)
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);
}
}
);
});
});
}
Run Code Online (Sandbox Code Playgroud)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/*"]
}
Run Code Online (Sandbox Code Playgroud)