javaScript googleExtention 擴充元件 瀏覽器 腳本

如何製作google擴充元件(腳本)

tom 2019/12/25 10:12:36
835

這篇文章關於如何撰寫基本的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 圖示
  }
}

>>>>>關於manifest_version詳細說明

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為tpu.thinkpower.com.tw才能觸發,那個當這元件在其他地方皆會變成灰白色無法啟用。

未啟用:

啟用:

mainTread.js:

/**
   * 在browser重啟始會紀錄addRules的狀態,下面這段不怕遺失
   * google建議在每頁都取消與重新註冊事件,因為每個頁面都會重新創建物件結構,雖然重建會增加效能損耗,相較之下(不銷毀)會比較快速完成運算邏輯
   * 
   */
  chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
    chrome.declarativeContent.onPageChanged.addRules([
      {
        //conditions 觸發擴充元件條件
        //actions 觸發時對應事件
        conditions: [
          new chrome.declarativeContent.PageStateMatcher({
            pageUrl: { hostEquals: "tpu.thinkpower.com.tw" }
          })
        ],
        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值,將其加一後顯示在頁面上並且設定回去。

>>>>>>關於activeTab可調用的功能

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擴充元件的入門說明,大家有興趣可以試試看,更詳細的內容都在下方連結內唷~

本篇文章參考>>>>>>>google官網上面的教學

 

下方為本來想寫成文章的萬年曆,但基本上沒用到太多extention的功能,一併放在github裡

gifff

github專案程式碼下載

 

 

 

tom