编写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变量
好了这几点是前置知识,下一篇文章来改造一个前端项目。