Chrome擴展開發(fā)——編寫一個自己的瀏覽器插件
這次的練習(xí)是做一個Chrome的擴展,分享一下入門開發(fā)過程。因為在消息傳遞那塊糾結(jié)了特別久,所以我會重點總結(jié)消息傳遞那塊。
- 這次做這個插件的功能很簡單,就是點擊按鈕后可以對當(dāng)前網(wǎng)頁的模塊進行選擇隱藏。
- 做這個插件一方面是練習(xí)實例,還有一方面是,有的時候查資料啊,邊上總有很多花花綠綠動來動去的小廣告!
- 很煩有木有,還根本不能關(guān)閉!就算有關(guān)閉按鈕,點擊了竟然還跳轉(zhuǎn)到廣告頁面了(゚Д゚≡゚Д゚)
- 所以就想做個小插件,讓自己可以選擇隱藏這些不想看的模塊。
配置文件
每一個擴展都有一個JSON格式的manifest文件,叫manifest.json。
所以***步我們將創(chuàng)建一個manifest.json文件。如下:
- {
- "manifest_version": 2, //固定的
- "name": "Cissy's First Extension", //插件名稱
- "version": "1.0", //插件使用的版本
- "description": "The first extension that CC made.", //插件的描述
- "browser_action": { //插件加載后生成圖標
- "default_icon": "cc.gif",//圖標的圖片
- "default_title": "Hello CC", //鼠標移到圖標顯示的文字
- "default_popup": "popup.html" //單擊圖標執(zhí)行的文件
- },
- "permissions": [ //允許插件訪問的url
- "http://*/",
- "bookmarks",
- "tabs",
- "history"
- ],
- "background":{//background script即插件運行的環(huán)境
- "page":"background.html"
- // "scripts": ["js/jquery-1.9.1.min.js","js/background.js"]//數(shù)組.chrome會在擴展啟動時自動創(chuàng)建一個包含所有指定腳本的頁面
- },
- "content_scripts": [{ //對頁面內(nèi)容進行操作的腳本
- "matches": ["http://*/*","https://*/*"], //滿足什么條件執(zhí)行該插件
- "js": ["js/jquery-1.9.1.min.js", "js/js.js"],
- "run_at": "document_start", //在document加載時執(zhí)行該腳本
- }]
- }
每個字段的信息我都用注釋標明了,接下來就重點說下一些重要字段。
需要注意:
chrome不允許擴展中的HTML頁面內(nèi)直接內(nèi)嵌js腳本,而要求所有的腳本都作為外部src來引入
browser_action
- 如果browser action擁有一個popup(即設(shè)置了default_popup),popup 可以包含任意你想要的HTML內(nèi)容,并且會自適應(yīng)大小。popup 會在用戶點擊圖標后出現(xiàn)。若沒有設(shè)置default_popup,將執(zhí)行chrome.browserAction.onClicked的內(nèi)容,若沒有設(shè)置,就什么都不執(zhí)行了。也就是如果設(shè)置了default_popup,就不會執(zhí)行chrome.browserAction.onClicked了。
- 和browser_action對應(yīng)的還有一個page_action,區(qū)別在于:Browser Action對在瀏覽器中加載的所有網(wǎng)頁都生效;Page Action針對特定的網(wǎng)頁生效。一個Extension最多可以有一個Browser Action或者Page Action。這里選用Browser Action。
background
- background是插件的運行環(huán)境。若設(shè)置了scripts字段,瀏覽器的擴展系統(tǒng)會自動根據(jù)scripts字段指定的所有js文件自動生成背景頁。也可以直接page字段,指定背景頁。兩者只能設(shè)置一個。
- 一般情況下,我們會讓將擴展的主要邏輯都放在 background 中比較便于管理。其它頁面可以通過消息傳遞的機制與 background 進行通訊。理論上 content script 與 popup 之間也可以傳遞消息,但不建議這么做。
消息傳遞
由于插件的js運行環(huán)境有區(qū)別,所以消息傳遞機制是一個重要內(nèi)容。
一次簡單的請求
如果僅需要給你自己的擴展的另外一部分發(fā)送一個消息(可選的是否得到答復(fù)),你可以簡單地使用chrome.extension.sendRequest()或者chrome.tabs.sendRequest()方法。這個方法可以幫助你傳送一次JSON序列化消息從content script到擴展,反之亦然。如果接受消息的一方存在的話,可選的回調(diào)參數(shù)允許處理傳回來的消息。
sendRequest() 是Chrome33之前的API,33之后還是使用sendMessage()吧。
1.內(nèi)容腳本發(fā)送消息到擴展程序
- chrome.extension.sendMessage({hello: "Cissy"}, function(response) {
- console.log(response.farewell);
- });
2.擴展程序發(fā)送消息到內(nèi)容腳本
- chrome.tabs.sendMessage(tab.id, {hello: "Cissy"}, function(response) {
- console.log(response.farewell);
- });
3.接收消息
chrome.extension.sendMessage()向擴展內(nèi)的其它監(jiān)聽者發(fā)送一條消息。此消息發(fā)送后會觸發(fā)擴展內(nèi)每個頁面的chrome.extension.onMessage()事件。
我用的是長時間的保持連接,原理差不多,就是調(diào)用接口的區(qū)別,所以就不具體介紹這個了 詳細的可以看開發(fā)文檔
長時間的保持連接
background 和 popup
同一個Extension的Extension Page(包括background、popup、tab、infobar、notification)都是運行在同一個進程中的,所以background 和 popup 之間可以直接相互調(diào)用對方的方法,不需要消息傳遞。
1.popup調(diào)用background中變量或方法
- var bg = chrome.extension.getBackgroundPage();//獲取background頁面
- console.log(bg.a);//調(diào)用background的變量或方法。
2.background調(diào)用popup中變量或方法
- var pop = chrome.extension.getViews({type:'popup'});//獲取popup頁面
- console.log(pop[0].b);//調(diào)用***個popup的變量或方法。
這里要注意一定要指明type,如果沒有指定,則獲取Background Page之外的所有Extension Page的window對象 。(。•ˇ‸ˇ•。)這個地方真的糾結(jié)好久。然后就是background是一個運行在擴展進程中的HTML頁面。它在你的擴展的整個生命周期都存在,而popup是在你點擊了圖標之后才存在,所以,在獲取popup變量時,請確認popup已打開。
background 和 content
持續(xù)長時間的保持會話需要在content script和擴展建立一個長時間存在的通道。當(dāng)建立連接,兩端都有一個Port 對象通過這個連接發(fā)送和接收消息。
1.內(nèi)容腳本發(fā)送消息到擴展程序
- var bac = chrome.extension.connect({name: "ConToBg"});//建立通道,并給通道命名
- bac.postMessage({hello: "Cissy"});//利用通道發(fā)送一條消息。
2.擴展程序發(fā)送消息到內(nèi)容腳本擴展程序發(fā)送消息到內(nèi)容腳本與前面類似,但需要指定哪個標簽需要連接,(獲取tab.id的方法我試了很多,但只有下面這個有效,所以如果大家有什么其他有效的方法,求求求分享!!)
- chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {//獲取當(dāng)前Tab
- var cab = chrome.tabs.connect(tabId, {name: "BgToCon"});//建立通道,指定tabId,并命名
- cab.postMessage({ hello: "Cissy"});//利用通道發(fā)送一條消息。
- }
3.接收消息為了處理正在等待的連接,需要用chrome.extension.onConnect 事件監(jiān)聽器,對于content script或者擴展頁面,這個方法都是一樣的
- chrome.extension.onConnect.addListener(function(bac) {//監(jiān)聽是否連接,bac為Port對象
- bac.onMessage.addListener(function(msg) {//監(jiān)聽是否收到消息,msg為消息對象
- console.log(msg.hello);
- })
- })
安裝調(diào)試
設(shè)置 —>拓展程序—>加載已解壓的拓展程序—>選擇文件就行了,記得要打開開發(fā)者模式哦
總結(jié)
插件功能的開發(fā)我就不寫了,實現(xiàn)起來比較簡單,這篇文章就當(dāng)是chrome拓展開發(fā)的學(xué)習(xí)筆記了,不足之處還望指出,***還是放一下插件源碼吧,寫的比較亂很多沒用到的代碼也沒刪掉,因為是練習(xí)中用到的。嗯嗯好了去吃飯。