如何製作google擴充元件(腳本)
這篇文章關於如何撰寫基本的chrome擴充功能,可以在瀏覽網頁時客製化一些自己的需求,或是在頁面做一些變動。
chrome線上應用程式商店已經有許多腳本可以使用
比較推薦的如:
google翻譯、遠方(新分頁背景)、阻擋廣告(youtube)、vue.js devtools(查看vue組建狀態)、tamperMonkey(幫你將寫好的腳本自動載入)
Step1 建構擴充元件
Step2 擴充元件主流程控制
Step2-1 讀取chrome.declarativeContent.onPageChanged
Step2-2 存取 chrome.storage
Step2-3 增加使用者設定選項
建構擴充元件
首先來做一個最基本的擴充元件吧,在wordspace中建立一個叫做manifest.json檔案:
{
"name": "Hello Extensions", //項目名稱
"description": "Base Level Extension",//敘述
"version": "1.0", //你的應用程式版本
"manifest_version": 2, //google編譯器版本,此篇版本為2
"browser_action": {
"default_popup": "hello.html",// 點擊此圖案對應個畫面
"default_icon": "dog.png" //icon 圖示
}
}
hello.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h1>hello</h1>
</body>
</html>
接著到google的設定頁面 chrome://settings/
點選擴充功能:
先將右上角的開發人員模式打開,再點選左上角的載入未封裝項目:
剛剛所設定的小圖案就會出現在chrome右上角的擴充功能中,點擊就會出現剛剛hello.html的畫面:
擴充元件主流程控制
接下來就是擴充元件與網頁溝通部分,擴充元件首先會先跑一次安裝,可以設定在哪些條件下才出現元件,此為主流程。 當你每次點選擴充元件時,會觸發一個showPageAction 事件,出現擴充元件畫面此畫面為子流程。 子流程可以向主流程溝通,也能對當前網頁進行處理。
以下會以此manifest.json中檔案分開進行解說,主流程mainTread.js,主要畫面popup.html :
{
"name": "Step2",
"version": "1.0",
"description": "擴充元件主流程控制",
"permissions": ["activeTab", "storage", "declarativeContent"],
"background": {
"scripts": ["mainThread.js"],
"persistent": false
},
"page_action": {
"default_popup": "popup.html",
"default_icon": {
"16": "images/get_started16.png",
"32": "images/get_started32.png",
"48": "images/get_started48.png",
"128": "images/get_started128.png"
},
"icons": {
"16": "images/get_started16.png",
"32": "images/get_started32.png",
"48": "images/get_started48.png",
"128": "images/get_started128.png"
}
},
"options_page": "options.html",
"manifest_version": 2
}
mainTread.js中內容皆寫在chrome.runtime.onInstalled.addListener(function(){})內
讀取chrome.declarativeContent.onPageChanged
manifest.json增加declarativeContent權限:
"name": "Step2",
"version": "1.0",
.......
"permissions": ["declarativeContent"]
下面假設我們有個元件只會在host為www.tpisoftware.com才能觸發,那個當這元件在其他地方皆會變成灰白色無法啟用。
未啟用:
啟用:
mainTread.js:
/**
* 在browser重啟始會紀錄addRules的狀態,下面這段不怕遺失
* google建議在每頁都取消與重新註冊事件,因為每個頁面都會重新創建物件結構,雖然重建會增加效能損耗,相較之下(不銷毀)會比較快速完成運算邏輯
*
*/
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
chrome.declarativeContent.onPageChanged.addRules([
{
//conditions 觸發擴充元件條件
//actions 觸發時對應事件
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostEquals: "www.tpisoftware.com" }
})
],
actions: [new chrome.declarativeContent.ShowPageAction()]
}
]);
});
也能偵測頁面是否有要針對的特別蘭未來啟用擴充元件,或是一次設置兩種條件觸發一樣的事件:
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostEquals: 'www.google.com', schemes: ['https'] },
css: ["input[type='password']"]
}),
new chrome.declarativeContent.PageStateMatcher({
css: ["video"]
})
],
actions: [ new chrome.declarativeContent.ShowPageAction() ]
對於出現條件還有更多的方法 >>>>>conditions相關的詳細方法
存取 chrome.storage
當我們在元件觸發時需要讀取一些固定的值,或是有些值需要跨頁面或是持續運算時,可以存取在storage
先增加storage權限:
"name": "Step2",
.......
"permissions":["storage","declarativeContent"]
storage 又分為storage.sync和storage.local,差異在於是否會同步到使用者其他裝置的chrome,但在離線狀態下,兩者的行為是一樣的。 storage裡面有onChange事件,可以監測是否有storage的異動,但在第一次設定值的時候,是不會觸發onChange事件的。 此外,storage裡面內容並不會加密,因使不建議儲存機密資料。
在主流程監控記憶體存取的狀態(mainTread.js):
chrome.storage.onChanged.addListener(function(changes, namespace) {
// 監控主流程的storage變化
console.log("storage change");
for (var key in changes) {
var storageChange = changes[key];
console.log(
'Storage key "%s" in namespace "%s" changed. ' +
'Old value was "%s", new value is "%s".',
key,
namespace,
storageChange.oldValue,
storageChange.newValue
);
}
});
/****
*
* chrome.storage.sync
* chrome.storage.local
* 差異為是否會同步到在同使用者個其他裝置chrome
* local為本地裝置
* 但若是離線狀態
* storage.sync 等同於 storage.local
*/
// 監控主流程的storage變化
chrome.storage.sync.set({ color: "#3aa757" }, function() {
console.log("The color is green.");
});
chrome.storage.local.set({ testChange: "a" }, function() {
// 新增欄位不會觸發change
});
chrome.storage.local.set({ testChange: "b" }, function() {
// 這會觸發change
});
chrome.storage.local.set({ testChange: "c" }, function() {
// 這也會觸發change
});
chrome.storage.local.set({ count: 0 }, function() {
// 設定count
});
在此用了許多log,我們可以透過在擴充功能管理,將應用程式載入後,可以點選inspect(背景頁面),可以進行偵錯,有程式碼異動時,也可以按重新整理按鈕,不需重新載入:
onChange事件在新增欄位時不會觸發,但如果將擴充程式移除後重新載入,所有值會被設置成undefine,就會觸發onChange事件:
在上面有在storage設定一個欄位color,並且給予他一個色碼的值,我們要將他設定在使用者網頁上和擴充應用的popup上,於是我們新增popup.js在popup.html中引用,新增三個button,changeColor:改變擴充元件顏色,changeColorTest:改變使用者頁面的顏色,test顯示使用者點擊擴充元件次數。
改變到使用者頁面需要取得activeTab的權限:
"name": "Step2",
.......
"permissions":["activeTab","storage","declarativeContent"]
popup.html:
<!DOCTYPE html>
<html>
<head>
<style>
button {
height: 30px;
width: 30px;
outline: none;
}
</style>
</head>
<body>
<button id="changeColor"></button>
<button id="changeColorTest"></button>
<button id="text"></button>
<script src="popup.js"></script>
</body>
</html>
對三個按鈕做初始化,changeColor點擊時會去取得storage中color欄位的值,並將本身的圖片與value改為此值。 changeColorTest將changeColor的value取出,
取得當前分頁,並且在該頁面執行js,更改分頁body顏色。 text則是取得count值,將其加一後顯示在頁面上並且設定回去。
popup.js:
(function() {
let changeColor = document.getElementById("changeColor");
changeColor.onclick = function() {
chrome.storage.sync.get("color", function(data) {
changeColor.style.backgroundColor = data.color;
changeColor.setAttribute("value", data.color);
});
};
let changeColor2 = document.getElementById("changeColorTest");
changeColor2.onclick = function(element) {
let color = changeColor.value;
chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
chrome.tabs.executeScript(tabs[0].id, {
code: 'document.body.style.backgroundColor = "' + color + '";'
});
});
};
chrome.storage.local.get(["count"], function(result) {
console.log("Value currently is " + result.count);
chrome.storage.local.set({ count: ++result.count }, function() {
console.log("set count", result.count);
// 設定count測試進入時間
});
document.getElementById("text").textContent = result.count;
});
})();
增加使用者設定選項
設定新增使用者選項設定
{
"name": "Step2",
......
"options_page": "options.html",
}
options.html
<!DOCTYPE html>
<html>
<head>
<style>
button {
height: 30px;
width: 30px;
outline: none;
margin: 10px;
}
body {
height: 200px;
width: 200px;
}
</style>
</head>
<body>
<div id="buttonDiv"></div>
<div>
<p>Choose a different background color!</p>
</div>
</body>
<script src="options.js"></script>
</html>
點擊顏色則將storage內color值改為那個顏色
options.js
let page = document.getElementById("buttonDiv");
const kButtonColors = ["#3aa757", "#e8453c", "#f9bb2d", "#4688f1"];
function constructOptions(kButtonColors) {
for (let item of kButtonColors) {
let button = document.createElement("button");
button.style.backgroundColor = item;
button.addEventListener("click", function() {
chrome.storage.sync.set({ color: item }, function() {
console.log("color is " + item);
});
});
page.appendChild(button);
}
}
constructOptions(kButtonColors);
以上為建置google擴充元件的入門說明,大家有興趣可以試試看,更詳細的內容都在下方連結內唷~
下方為本來想寫成文章的萬年曆,但基本上沒用到太多extention的功能,一併放在github裡
github專案程式碼下載