将一个前端项目改写为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变量

结语

好了这几点是前置知识,下一篇文章来改造一个前端项目。

相关文章
相关标签/搜索