前言
这是一篇关于Chrome扩展插件入门、Vue.js入门的小练习,功能是:在当前浏览的页面点击扩展图标,并点击保存之后,该页面就会存在你的新标签页中。其实就是一个可视书签的内容。
欢迎大家指出代码的不足之处,很多时候都是自己学习自己码代码,太需要别人的意见了。
Demo代码
代码戳这里
Chrome插件预备知识
首先给出一本参考的中文书籍,在练习的过程中有帮到忙。当然,最权威的还是官方文档,只不过像我这种英文不太好星人只能拣自己看得懂的看了。另外还有官方文档的中文版,在英文版看不懂的时候用。
manifest.json
这个文件其实就是你的扩展插件的一个说明书。来人,上代码!
{ // 前三个必填 "manifest_version": 2, "name": "bookmark", "version": "1.0", "description": "This extension shows bookmarks", "browser_action": { "default_icon": "icon.png", "default_popup": "popup.html" }, "chrome_url_overrides": { "newtab": "main.html" }, "content_scripts": [ { "matches": ["*://*/*"], "js": ["jquery-3.2.1.min.js", "html2canvas.js", "canvas2image.js","contentScripts.js"] } ], "permissions": [ "tabs" ] }
前三个必填的我不想说了,无非就是版本、名称之类的。
- browser_action
这一项是设置你的扩展在浏览器窗口上的小图标,以及点击这个图标弹出的页面的,你会发现文档的写法跟我有些不一样,因为我有点懒,这样写字数比较少,省事儿。同学们不要学我呦。
- chrome_url_overrides
顾名思义,重写chrome相关的页面。我这里要重写的是“new tab”,即新标签页,页面的内容入口在main.html。你还可以重写别的页面,比如书签管理页面等,可以参考文档
- content_scripts
中文翻译过来应该叫内容脚本,它可以运行在你指定的页面之中,可以拿到指定页面的一些信息。指定的页面就是“matches”这一项了。在本练习中,可以看到用正则匹配了所有页面,因为毕竟是要做书签嘛。“js”这一项是一个数组,里面放的就是你在指定页面里用的脚本,前三个都是依赖,最后一个contentScripts.js才是真正搞事情的脚本,注意依赖是有顺序的噢,其实与在<head>标签里引<script>标签是一回事情。
但其实,我总觉得这么个小demo也许用不到内容脚本,但是水平有限,找不到更好的实现方法,期待大牛与我交流。
- permission
向chrome申请一些权限,这里我申请了tab 浏览器选项卡的权限,因为做书签时我需要当前tab的url。还有一些别的权限,请参考文档
思路整理
通过以上的说明书,应该大致明白这个扩展插件是怎么回事了,接下来该考虑怎么实现功能。
- 首先,点击扩展图标,弹出一个页面(popup.html),这个页面有个保存按钮,点击这个按钮应当有相应的事件处理函数,此函数的功能就是获取我当前浏览页面的截图以及url等信息,可以写一个js脚本,即popup.js
拿到url的信息比较简单,chrome.tabs这个API下有一些methods,查看文档发现chrome.tab.query可以query到当前的选项卡,成功拿到页面的url和title
但是问题来了,popup.html虽然是在我当前浏览的窗口上弹出来的,但是是与当前页面独立,如何能获取当前页面的截图呢?
如果你在认真看之前的内容的话,现在脑子蹦出来的应该是——content Scripts!
没错,是它 是它 就是它!上文提到了,这个内容脚本可以运行在指定的页面之中,并且貌似可以拿到当前页面的dom结构,所以,可以在contentScripts.js中使用html2canvas插件拿到截图,并且用canvas2html把图片转成base64格式,至于为什么要转成base64,就要想想拿到这个截图之后干什么了
- 获得当前页面的截图之后,应当把它传递到我们重写的新标签页下(new tab,新选项卡),即main.html(所以转成base64是为了能把图片传到main.html,我发现只有这样传递才能成功),这个页面也应当有个脚本来接收这个图片并且做一些处理,可取名为main.js
然后问题又来了,这几个页面完全独立,要怎么传递东西呢?所以接下去要介绍的是chrome扩展页面间的通信。
Chrome扩展页面间的通信
在查阅这部分的资料时,还蛮头疼的。命令有点多,而且比较长,对于我这样的懒人来说简直是理不清。终于,很多东西不懂不懂,多看几遍也就摸出门道了。
- 先来理一理,需要收发消息的脚本们。
popup.js -> contentScripts.js -> main.js
- 查阅文档发现,发消息有以下几种方式
chrome.runtime.sendMessage({msg: msg})
chrome.tab.sendMessage(tab的id, {msg: msg})
- 接收消息的方法
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){})
发送者发来的对象都在request中,可以用request.msg读取
你有需要发回的消息时可以用使用sendResponse
接下来就把这几个发送和接收的方法写到各自的脚本中啦。注意发送消息到content Script,必须使用chrome.tabs.sendMessage。
- popup.js——chrome.tabs.sendMessage
- contentScripts.js——chrome.runtime.onMessage.addListener和chrome.runtime.sendMessage
- main.js——chrome.runtime.onMessage.addListener
至此,整个扩展插件的骨架都搭好了。
最前面是不是提到了Vue,好吧其实一开始我是想做个vue的demo来学习学习vue的,只是没想到这个扩展页面上的东西太简单,反而在学习Chrome扩展开发花了更多的时间。Vue.js的相关内容也有,就是太简单了,大家可以去看看源码。
问题
- 截屏不是对所有页面都有效
- 只想对页面窗口大小的页面进行截屏,不知道该怎么做
- 是否可以不使用html2canvas这种插件来实现截屏的效果
问题解决
对于截屏这个问题,终于找到了正确的方法。其实近在眼前,怪我没仔细看文档。
- chromes.tabs.captureVisibleTab 便可以截取可见页面
虽然使用html2canvas方法繁琐,但也帮助我明白了chrome扩展间的通信方法,因祸得福♪(^∀^●)ノ