如何開發Chrome擴充套件程式

jobbole發表於2013-08-27

  我真的很喜歡Chrome瀏覽器,這種感覺是在我發現建立Chrome擴充套件竟然是如此的容易之後才有的。如果你懂得基本的HTML、CSS、JavaScript,那你就有了擴充套件Chrome瀏覽器需要的所有知識。這篇文章將會是一個讓你對Chrome擴充套件有基本瞭解的速成班,但我在這個方面也不敢自稱是專家,如果你在文章中發現任何錯誤,請一定讓我知道。

  開始

  為了著手建立你的擴充套件程式,你只需要為你的擴充套件建立一個資料夾。程式所必須的檔案只有manifest.json.,不過也推薦準備一些圖片用作圖示,和至少一個JavaScript以提供功能。一般來說還會包含HTML文件、樣式表、圖片等等其他的資源。

  Manifest檔案

  每個擴充套件都必須在其根目錄下包含一個manifest.json檔案。

  這個檔案裡面宣告瞭擴充套件的名稱、版本、許可權、設定選項和其他的一些和擴充套件相關的後設資料。Manifest v1早在Chrome 18便已被棄用,而且會根據這個時間表逐漸淘汰使用Manifest v1的擴充套件。如果你在參考一些舊擴充套件的Manifest檔案的話,請確認新增"manifest_version": 2.

  Google釋出的Manifest v2中支援的域

  後臺頁

  大多數擴充套件都會在其manfiest.json檔案內有這樣的內容:

{
  "background": {
    "scripts": ["index.js", "other.js"]
  }
}

  這一段程式碼指定了兩個需要被載入而且要保持在後臺執行的指令碼,這些指令碼會在擴充套件的後臺頁執行。後臺頁是一個在擴充套件的程式中生成並執行的頁面,存在時間會和擴充套件的生命週期等長。後臺頁可用來作為擴充套件的其他介面的控制器,用來維護某個狀態或者保持某些活動。如果你需要用後臺頁來宣告一些標記來用,可以把一個HTML檔名指定給page選項。

  事件頁

  後臺頁會從擴充套件被載入的時候被裝載,而且會一直留在記憶體裡。這是因為如果有些狀態需要被長時間維護,或者需要被擴充套件的其他部分訪問。但是如果你沒有這個需求,那麼應該儘可能的使用事件頁。事件頁其實只是相當於一個包含了”persistent”: false條目的後臺頁,這一行語句告訴Chrome可以不需要把後臺頁保留在記憶體裡。相對來說,事件頁也會在最開始被裝載,但是一旦指定的指令碼執行完畢,事件頁便會從記憶體解除安裝,而且會在需要的時候被再次載入(比如用來回應某些操作)。

  以上便是在為擴充套件新增功能之前所需要知道的。

  互動

  利用Google提供的大量API,你的擴充套件與瀏覽器互動或者為使用者提供功能都變得方便。

  chrome.* APIs

  Chrome的程式和擴充套件程式都非常喜歡呼叫chrome.* APIs,這些API可以讓你通過不同的方式來操控瀏覽器,API通常會在後臺指令碼里面被呼叫,這是我找到的一些常用API:

  • chrome.tabs 標籤頁:新建、重新整理、關閉、訪問和操控標籤頁
  • chrome.history 歷史:訪問使用者瀏覽歷史
  • chrome.bookmarks 書籤:新增、編輯、移除和搜尋使用者書籤
  • chrome.events 事件:監聽或者管理瀏覽器發生的事件
  • chrome.commands 命令:新增或者改變鍵盤命令
  • chrome.contextMenus 右鍵:新增條目到右鍵下文選單
  • chrome.omnibox 多功能框(位址列):新增多功能框關鍵字,使使用者可以向擴充套件傳送指令或者啟用擴充套件

  其他API

  Chrome程式和擴充套件程式通常也會用到其他的API,包括如本地儲存、地理位置、快取、畫布等新型的HTML5 API。你也可以用普通的JavaScript或者webkit API來實現。

  宣告許可權

  有些Chrome API的功能必須要在manifest.json檔案中宣告相關許可權才能被呼叫,通過在permissions 域中把值設成相應許可權名稱,或者是通識符組成的陣列。

{
  "permissions": [
    "contextMenus",
    "tabs",
    "https://google.com/*",
    "https://developer.mozilla.org/*"
  ]
}

  在這一段宣告程式碼中,陣列中的頭兩個字串是分別用來為chrome.contextMenus和chrome.tabs  的API授權的,最後的兩個字串則是用來匹配以 https://google.com/ 和 https://developer.mozilla.org/ 開頭的地址。

  使用者介面

  Chrome擴充套件的使用者介面有著嚴格的限制,但是根據擴充套件的需要卻可以有不同形式的介面。

  瀏覽器按鈕

  瀏覽器按鈕允許你在右上角放置一個的16 x 16畫素的圖示,如果擴充套件應用的介面是全域性的,而不是針對某個頁面,那就應該使用瀏覽器操作。如果要使用瀏覽器按鈕,你必須在manifest.json中的browser_action域中做如下宣告:

{
  "browser_action": {
    "default_icon": {                    
      "19": "images/icon19.png",
      "38": "images/icon38.png"
    },
    "default_title": "tooltip text here",
    "default_popup": "popup.html"
  }
}

  一個瀏覽器按鈕可以有一個圖示、提示、文字標記和一個彈出內容,文字標記可以將極少的文字(4字元)動態的覆蓋在瀏覽器操作的圖示上,你也可以通過chrome.browserActionAPI來對瀏覽器按鈕相關的事件做出反應。

  頁面按鈕

  面按鈕允許你在多功能欄(位址列)右邊新增一個按鈕,其實他和瀏覽器按鈕很相似,區別之處在於頁面按鈕是專門用來處理某些指定的頁面的。頁面按鈕必須在manfiest.json中宣告, page_action域的使用和瀏覽器按鈕一樣。頁面按鈕可以通過chrome.pageAction API控制,可以在不同的標籤頁中靈活的顯示或者隱藏。頁面按鈕也可以設定圖示、提示和彈出內容,和瀏覽器按鈕不同的是其沒有文字標記功能。

  右鍵選單

  右鍵選單是另一個提供使用者介面,方便使用者和擴充套件互動的方式。Chrome的右鍵選單通過右鍵啟用,但根據啟用內容的變化,選單內容也會做相應改變。

  chrome.contextMenusAPI允許你向為不同內容啟用的右鍵選單新增專案,若要使用此API,則在manifest.json檔案中宣告相應的contextMenus許可權。

  目前可用的啟用內容有:

  all, page, frame, selection, link, editable,image, video,  audio

  對應:所有內容、頁面、框架、選擇、連結、可編輯、影象、視訊、音訊,以下這個例子需要contextMenus 和tabs許可權,他可以使擴充套件為右鍵選單新增一個根專案,然後新增一個子選單,用來複制當前的頁面到一個新選項卡。

var root = chrome.contextMenus.create({
   title: 'MyExtension',
   contexts: ['page']
}, function () {
   var subMenu = chrome.contextMenus.create({
       title: 'Duplicate Tab'
       contexts: ['page'],
       parentId: root,
       onclick: function (evt) {
           chrome.tabs.create({ url: evt.pageUrl })
       }
   });
});

  多功能框

  Chrome把位址列/搜尋欄稱為多功能框,通過chrome.omnibox API,他可以讓擴充套件有另一個介面。通過API 可以設定一個特定的啟用字串,當這個字串被鍵入多功能框時擴充套件便可以對其做出反應。在manifest.json中做如下宣告:

{
  "omnibox": {
    "keyword": "ext-"
  }
}

  這部分程式碼會把ext-作為啟用字串,當使用者鍵入ext-並按下SPACE鍵或者TAB鍵時擴充套件會被啟用。啟用字串必須通過manifest.json檔案宣告,故也不能通過JavaScript來更改。使用者可以通過右鍵單擊多功能框—–修改搜尋引擎來更改。啟用字串是大小寫敏感的,同時想為一個擴充套件宣告多個啟用字串也是不可以的。

  chrome.omnibox API可以讓你新增啟用字串被鍵入之後的修改或者輸入的事件處理器。

  選項頁面

  選項頁面是一個的常見的使用者介面,在chrome://extensions裡可以通過單擊擴充套件右邊的選項按鈕來開啟。通常這個頁面會和儲存API結合使用,以用來在計算機上為使用者儲存設定。而使用指令碼通過chrome.tabsAPI來開啟選項頁面也是可以的。

  頁面過載

  頁面過載允許你完全替代一個以下指定頁面(一個擴充套件程式只能過載一個頁面)

  • 書籤管理器
  • 通過訪問chrome://bookmarks或者Chrome選單開啟的頁面
  • 歷史
  • 通過訪問chrome://history或者Chrome選單開啟的頁面
  • 新選項卡
  • 通過訪問chrome://newtab或者新建選項卡出現的頁面

  這些被替換的頁面必須在manifest.json檔案中如下宣告chrome_url_overrides域:

{
  "chrome_url_overrides": {
    "bookmarks": "newBookmarkManager.html"
  }
}

  內容指令碼

  內容指令碼是和你的擴充套件有關,在網頁中執行的指令碼。這個指令碼可以讓你訪問頁面裡相應的DOM元素,你可以像這樣在manifest.json裡通過指定content_scripts域定義一個內容指令碼陣列:

{
  "content_scripts": [
    {
      "matches": ["http://www.google.com/*"],
      "css": ["custom-google-styles.css"],
      "js": ["custom-google-script-1.js", "custom-google-script-2.js"]
    },
    {
      "matches": ["http://*"],
      "css": ["global-styles.css"],
      "js": ["global-script.js"]
    }
  ]
}

  你也可以用通過chrome.tabs API以動態的把JavaScript或者CSS注入網頁

  內容指令碼有以下限制:

  • 不能使用chrome.* API (chrome.extension的部分除外)
  • 不能使用由擴充套件指令碼定義的變數或函式
  • 不能使用由網頁所定義的變數或函式
  • 不能使用由其他內容指令碼定義的變數或函式

  內容指令碼可以通過訊息傳遞間接的使用chrome.* API,或者是和擴充套件指令碼互動。

  一些例子

  Chrome有一個非常棒的樣例程式頁面,你可以通過他們呼叫了哪些API來搜尋樣例擴充套件,你也可以閱讀我第一個擴充套件程式MDNJump相關的文章MDNJump已放在GitHub

相關文章