將一個前端項目改寫爲chromo插件(一)

編寫第一個chrome插件?

編寫chrome插件徹底就是前端知識加上一些專門的知識。 假設pj1文件夾下有文件index.htmljavascript

<!DOCTYPE html>
<html>
<head>
    <title>Hi</title>
    <meta charset="utf-8"/>
    <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
    <div id="main">
    	hello,world
    </div>
   <script type="text/javascript">
        setTimeout(()=>{
            document.getElementById("main").innerText = "hi,saltfish"
        },1000)
   </script>
</body>
</html>
複製代碼

嗯,如今看來他只是普通的html,其實,你只要在當前文件夾下加上manifest.json文件,chrome瀏覽器就能夠把它識別爲插件,成爲瀏覽器右上角的小圖標。css

如何什麼是manifest.json,如何編寫?

manifest 是貨單的意思,這個文件就是chrome規定的的插件配置文件的名稱html

{
	"name": "My Extension",
    "version": "1.0",
    "manifest_version": 2,
    "browser_action": {
        "default_popup": "index.html"
    }
}
複製代碼

name、version不用解釋,manifest_version相似與XML的schema文件,用來約束manifest_version自身的格式,目前,它的值永遠是2。前端

default_popup做用:當用戶點擊插件的小圖標後,顯示的畫面,就是把它所引用的HTML渲染後獲得的。java

如何發佈?

在chrome瀏覽器訪問 chrome://extensions/ 就會看到git

點擊 LOAD UNPACKED 再選取存放文件的文件夾便可。你會馬上在瀏覽器又上角看到本身的插件。 點擊後會顯示index.html對應的內容

爲了統一規範,咱們能夠把index.html更名爲popup.html,同時記得修改"default_popup"的值github

關於popup.html

咱們能夠看到,chrome插件的UI是用HTML編寫的(相應的腳本也是js寫得),因此chrome插件對咱們前端開發者來講很是好學。chrome

每當咱們點擊小圖標時,chrome就會讀取配置文件中定義的HTML文件。json

在chrome插件的UI中,沒有title等的概念,因此咱們能夠吧一些沒用的標籤給刪除掉。api

css文件和通常前端如出一轍

在`style.css``添加

body{
    width: 300px;
    height: 300px;
    background-color: antiquewhite;
}
複製代碼

(記得在popup.html中引用哦) 在刷新插件,能夠看到

js腳本

細心的同窗可能注意到,在以前的popup.html中明明有腳本

<script type="text/javascript">
    setTimeout(()=>{
        document.getElementById("main").innerText = "hi,saltfish"
    },1000)
</script>
複製代碼

爲何頁面一直不刷新? 由於chrome官方規定js腳本只能引入,不能嵌入HTML(我也不知道爲何這樣規定) 添加標籤<script src="script.js"></script>並將腳本移動到對應位置,再刷新插件,你就能夠看到正確的結果了。

這裏的js腳本和通常的js環境相同,不過console.log 不能用,由於chrome也不知往哪裏打印結果,不過你可使用alert函數來調試代碼。

popup.html的生命週期

該文件在用戶點擊小圖標後加載,和你打開通常的網頁如出一轍,只不過對應的UI顯示在瀏覽器的右上角,每當你點擊其餘地方chrome就會關閉這個窗口,對應的js環境也會被銷燬,也就是說,你每次點擊小圖標,就會從新渲染HTML和css,並從新運行js代碼。

正是由於這個特性,popup.html以及他引入的js腳本,只處理UI相關。一些業務邏輯放在其餘地方,下面來介紹

確認下目錄結構

$ tree
.
├── manifest.json
├── popup.html
├── script.js
└── style.css
複製代碼
$ cat manifest.json
{
    "name": "My Extension",
    "version": "1.0",
    "manifest_version": 2,
    "browser_action": {
        "default_popup": "popup.html"
    }
}
複製代碼

background.js

將manifest.json修改成:

{
	"name": "My Extension",
    "version": "1.0",
    "manifest_version": 2,
    "browser_action": {
        "default_icon": {
            "19": "images/icon19.png"
        },
        "default_popup": "popup.html"
    },
    "background": {
        "scripts": [
            "background/bg.js"
        ]
    }
}
複製代碼

並添加background/bg.js文件, background字段定義的js代碼在打開瀏覽器時執行,知道瀏覽器關閉。

setInterval(()=>{
    alert((new Date()).toDateString())
},2000)
複製代碼

在bg.js添加上述代碼,發現瀏覽器一經加載,就不停彈出對話框,不論是否點擊了小圖標,無論你作了什麼操做,他都是一直執行。

如今註釋上述代碼

content_scripts

有時候咱們的插件但願作到: 當用戶打開某個網頁後,再進行操做。好比用戶打開github.com後,彈出「hi,it is github」。如何實現呢 再manifest.json添加:

"content_scripts": [
        {
            "matches": ["*://github.com/*"],
            "js": ["content/github.com.js"]
        }
    ]
複製代碼

並添加相應文件,在js代碼中寫上

alert("hi,it is github")
複製代碼

content_script是個數組,定義了一些url與script的聯繫,噹噹用戶訪問相應的網址的時候,chrome會等待頁面加載完成後,執行相應的js代碼。

content_script能夠訪問當前頁面的dom和localstorage,可是沒法訪問當前頁面的js變量

content_script在每次加載相匹配的頁面後執行,頁面被刷新後對應的content_script也會被重行執行。

三種js環境

咱們看到,咱們以前說起了三種js環境、background.js,content_script,popup.html引用的,如今來捋一捋他們的關係和區別

內容 background.js content_script popup.js
生命週期 瀏覽器加載後一直執行 打開相應url後執行 每次點擊圖標後執行
dom 沒有能操做的dom 能讀取當前頁面dom popup.html的dom
js變量 若是有多個bg.js,並列腳本間不共享js變量 與原生頁面的js變量隔絕,若是多個content_script匹配到同一個url,他們的一直執行,js變量依舊隔絕
localstorage 每個插件對應一個localstorage,被不一樣的bg.js共享 和當前url的localstorage共享 和當前插件共享(這是bg.js和popup.js一種通訊方式)

這幾點是我本身在學習中,不斷測試,獲得這幾點結論(測試過程就不寫了,很容易想到)。

確認下目錄

$ tree
.
├── background
│   └── bg.js
├── content
│   └── github.com.js
├── manifest.json
├── popup.html
├── script.js
└── style.css
複製代碼

頁面間通信

以前,說過,各中js代碼中的變量是不共享的,那麼咱們如何讓他們通信呢? 好比,當用戶訪問github.com時,讓content_script向bg.js 說一聲hello? chrome設計了一個接口api: 在github.com.js:

let message = "hello"
chrome.runtime.sendMessage(message, function(response){
    console.log(response)
});
複製代碼

bg.js

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse){
    alert(message)
    sendResponse({content:"hi,it is bg.js"})
});
複製代碼

刷新插件並打開github,發現彈出「hello",對應github頁面控制檯也打印出{content:"hi,it is bg.js"}

能夠看到:整個過程相似於HTTP請求,content_script發起一個請求,bg.js迴應。 並且運行直接傳遞js變量

結語

好了這幾點是前置知識,下一篇文章來改造一個前端項目。

相關文章
相關標籤/搜索