前言
我們常稱的 Chrome 插件(Chrome Extension)是指 Chrome 擴展程序,它的作用是增強瀏覽器功能。通常在Chrome商店中下載的擴展是.crx
后綴的壓縮包,安裝插件可以以壓縮包形式安裝,當你開啟開發者模式的時候,也可以加載已解壓的擴展程序,即至少包含一個manifest.json
文件和一個 html 或者 js 文件的的文件夾。
Chrome插件提供了很多實用API供我們使用,包括但不限於:書簽控制、下載控制、窗口控制、標簽控制、網絡請求控制,各類事件監聽、自定義原生菜單、完善的通信機制等。
本文多圖預警 🙃
Talk is cheap. Show me the code.
一、一個最簡單的 Chrome 擴展的組成示例
此示例由一個manifest.json文件和html文件和一個png圖片文件組成,是一個git 提交的emoji速查工具,功能非常的簡單,就是點擊彈出一個html頁面(下圖),以達到速查的目的,html里可以替換成任何你想要的內容。代碼戳這里 下載這份代碼,在 Chrome 里的擴展程序里打開開發者模式,加載已解壓的擴展程序即可體驗
manifest.json 基本配置
{
"manifest_version": 2, // 必填 用整數表示manifest文件自身格式的版本號。從Chrome 18開始,manifest_version就是2了
"name": "git commit emoji速查", // 必填 用來標識擴展的簡短純文本。這個文字將出現在安裝對話框,擴展管理界面,和store里面
"description": "git commit emoji對照表", // 描述擴種的一段字符串(不能是html或者其他格式,不能超過132個字符)
"version": "1.0.0", // 必填
"browser_action": { // 一個 browser action 可以擁有一個圖標,一個tooltip,一個badge和一個popup。
"default_icon": "icon.png", // 右上角的圖標
"default_title": "這是一個 git commit emoji 速查的Chrome插件", // 鼠標hover的文字
"default_popup": "popup.html" // 點擊圖標展示的html內容
}
}
幾個常用配置比較
二、Chrome插件的表現形式
1. 瀏覽器右上角(最常見)
不管有沒有開發過 Chrome 插件,我們最熟悉的 Chrome 插件一定是右上角插件圖標
一般功能上有兩種,一種是一直開啟狀態,點擊發生交互,展示彈窗之類的,在 manifest.json 配置的是 browser_action;一種是點擊開啟(例如屏蔽廣告等)功能,有些是在特定情況下才展示,比如vue的調試插件是在vue開發模式下才能開啟。page_action 則指的是只有當某些特定頁面打開才點亮的圖標,其他則是置灰。
2. 自定義右鍵菜單
鼠標右鍵的菜單
使用 chrome.contextMenus 實現
chrome.contextMenus.create({
id: 'page',
title: '測試右鍵菜單'
});
如果要在選中狀態的時候去監聽點擊事件,達到這樣的效果
注意:使用 chrome.contextMenus API 需要在 manifest.json 里生命權限 permissions 數組里加上 contextMenus
chrome.contextMenus.create({
id: 'baidu-search',
title: '使用百度搜索:%s',
contexts: ['selection']
});
chrome.contextMenus.onClicked.addListener(function(info, tab) {
switch(info.menuItemId){
case 'baidu-search':
chrome.tabs.create({url: 'https://www.baidu.com/s?ie=utf-8&wd=' + encodeURI(info.selectionText)});
break;
}
});
3. 覆蓋特定頁面
在 manifest.json 里添加 chrome_url_overrides,可以被替換的只有新標簽頁 newtab、歷史記錄頁 history、書簽頁 bookmarks 這三個選項,但是一個插件只能重寫一個默認頁
"chrome_url_overrides":
{
"newtab": "newtab.html"
}
4. 開發者工具
自定義開發者工具面板,大家熟悉的 vue 插件就是通過自定義開發者工具面板實現
通過 chrome.devtools API來實現
// 幾個參數依次為:panel標題、圖標(其實設置了也沒地方顯示)、要加載的頁面、加載成功后的回調
chrome.devtools.panels.create("TestPanel", "", "devtools.html", function(
panel
) {
console.log("自定義面板創建成功!", panel); // 注意這個log一般看不到
});
// 創建自定義側邊欄
chrome.devtools.panels.elements.createSidebarPane("Images", function(sidebar) {
// sidebar.setPage("devtools.html"); // 指定加載某個頁面
sidebar.setExpression('document.querySelectorAll("img")', 'All Images'); // 通過表達式來指定
// sidebar.setObject({aaa: 111, bbb: 'Hello World!'}); // 直接設置顯示某個對象
});
5. 選項頁
選項頁實際上是指插件的詳細信息介紹,配置在 manifest.json 里的options_ui
"options_ui": {
"page": "options.html",
"browser_style": true
},
6. 搜索建議
manifest.json里配置觸發關鍵詞,配置后再地址欄輸入關鍵詞后按空格鍵觸發插件搜索建議
"omnibox": { "keyword" : "go" }
background.js 里 使用chrome.omnibox API
chrome.omnibox.onInputChanged.addListener((text, suggest) => {
console.log('inputChanged: ' + text);
if(!text) return;
if(text == 'c') {
suggest([
{content: 'extension' + text, description: 'chrome://extension'},
{content: 'bookmarks' + text, description: 'chrome://bookmarks'},
{content: 'history' + text, description: 'chrome://history'}
]);
}
});
// 當用戶接收關鍵字建議時觸發
chrome.omnibox.onInputEntered.addListener((text) => {
console.log('inputEntered: ' + text);
if(!text) return;
var href = '';
if(text.endsWith('extension')) href = 'chrome://extension'
else if(text.endsWith('history')) href = 'chrome://history'
else href = 'chrome://bookmarks'
openUrlCurrentTab(href);
});
// 獲取當前選項卡ID
function getCurrentTabId(callback)
{
chrome.tabs.query({active: true, currentWindow: true}, function(tabs)
{
if(callback) callback(tabs.length ? tabs[0].id: null);
});
}
// 當前標簽打開某個鏈接
function openUrlCurrentTab(url)
{
getCurrentTabId(tabId => {
chrome.tabs.update(tabId, {url: url});
})
}
桌面通知
chrome.notifications API ,首先在 permissions 里聲明 notifications 權限,再在background里創建通知
chrome.notifications.create('', {
type: 'basic',
iconUrl: 'icons/icon.png',
title: '這是標題',
message: '您剛才點擊了自定義右鍵菜單!'
});
三、消息通信
Chrome插件中有2種通信方式,一個是短連接(chrome.tabs.sendMessage和chrome.runtime.sendMessage),一個是長連接(chrome.tabs.connect和chrome.runtime.connect)
sendMessage 發消息 onMessage 接收監聽消息
connect 建立長連接 通過 onConnect 接收監聽消息
四、用 vue 開發 Chrome 插件
用 vue 開發 Chrome 插件實際上是頁面都通過vue來開發,最后打包之后的文件還是包含 html、js、靜態資源文件和 manifest.json 幾個 Chrome 必要組成部分,vue是通過模板引擎生成對應的想要的頁面。
https://github.com/Kocal/vue-web-extension 是一個通過命令生成的vue開發Chrome插件模板cli
本文代碼演示是用的這個模板