編寫chrome插件徹底就是前端知識加上一些專門的知識。 假設pj1
文件夾下有文件index.html
javascript
<!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
咱們能夠看到,chrome插件的UI是用HTML編寫的(相應的腳本也是js寫得),因此chrome插件對咱們前端開發者來講很是好學。chrome
每當咱們點擊小圖標時,chrome就會讀取配置文件中定義的HTML文件。json
在chrome插件的UI中,沒有title
等的概念,因此咱們能夠吧一些沒用的標籤給刪除掉。api
在`style.css``添加
body{
width: 300px;
height: 300px;
background-color: antiquewhite;
}
複製代碼
(記得在popup.html中引用哦) 在刷新插件,能夠看到
細心的同窗可能注意到,在以前的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函數來調試代碼。
該文件在用戶點擊小圖標後加載,和你打開通常的網頁如出一轍,只不過對應的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"
}
}
複製代碼
將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添加上述代碼,發現瀏覽器一經加載,就不停彈出對話框,不論是否點擊了小圖標,無論你作了什麼操做,他都是一直執行。
如今註釋上述代碼
有時候咱們的插件但願作到: 當用戶打開某個網頁後,再進行操做。好比用戶打開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環境、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變量
好了這幾點是前置知識,下一篇文章來改造一個前端項目。