关闭页面特效

动手做第一个Chrome插件

  Chrome插件是令人惊讶的简单,一旦你弄懂它的工作和实现原理。它是由一部分HTML,一部分Js,然后混合了一个叫做manifest.json的Json文件组合而成的整体。这意味着你可以使用你最擅长的js框架去实现它。

  如果你还是一个Chrome插件的新手并且想尝试写一个的话,下面的文章将会带领大家并且尝试让大家理解Chrome插件的工作机制。这篇文章将会讲述每一块架构,以及相互之间的联系和插件的一般化形式。

1|0架构


 

  Chrome插件中的文件大体上可以分成2部分:Chrome插件中确确实实存在的文件,并且是应用程序级别的,如上图的Chrome Extension Scripts以及注入到每个网页Dom当中的文件(如Content Scripts 或者Injected Scripts).这些文件都被放在manifest.json当中,Chrome内部会自动识别不同个文件的作用。

  在任何时候,popup和background都只有一份,相比较起来,如果你有多个Tab(这里的Tab指的是Chrome当中的选项卡,也就是一个窗口页面),那么Content Scripts和 Injected Scripts会运行在每一个Tab当中,也就是可以跨选项卡。当然,你可以指定往哪个Tab当中去注入Scripts,也就是说,注入操作是可选择的。

  下面是一些它们如何工作的细节:

2|0Manifest.json


  • 这个Json文件是把backgrounds, popups, content scripts 和injected scripts 放在一起,并以结构化的方式书写。
  • 设置扩展,如Permission。
  • 设置扩展的基本信息。

3|0Background


  • Javascript文件总是运行在后台(在老版本的Chrome当中,background是html文件并且嵌入了javascript).
  • 没有显示界面。
  • 有Chrome应用程序级别命令的访问权限。
  • 有使用所有Chrome API的权限

4|0Popup


  • 点击插件图标会显示出Html和Javascirpt.
  • 也拥有应用程序级别的权限(和background一样)
  • 只有当Chrome插件的图标点击的时候才触发。
  • 对所有的pop-up Chrome API有使用权限。

5|0Content Scripts


  • 拥有一部分Api的使用权限(比如从backgorund监听消息)
  • 对于页面Dom有完整的访问权限,但是对于任何window级别的对象没有访问权限(比如全局变量),对于frame也没有访问权限;这是因为安全限制。
  • Content scripts运行在介于插件和页面之间,全局的window对象是和页面/插件全局命名空间完全不同的。

6|0Injected Scripts


  • 和Contente Scripts 一样,只拥有部分Api的使用权限
  • 注入当前Tab的网页当中,并不与插件进行通信。

7|0关联关系


 

  他们之间的联系只要你弄懂了整体的架构,我相信就会很明了。

  在应用程序级别的部分是可以有互相访问的权限的。比如Popup文件能用chrome.extension.getBackgroundPage()访问background里面的东西,这就好像Backbone 视图可以访问他们的Model和Collection。

  Content Scripts是存在于每个独立的Dom页面,和background和popup用message的方式进行通信交流。特别的,它可以使用chrome.tabs.sendMessage和chrome.runtime.onMessage.addListener去向对方发送消息。这和Backbone 的事件系统很像.

  Injected Scripts和Content Scripts的不同在于它不能监听或者发送消息给其他的Chrome插件部分。

8|0结构


  组织你的Chrome插件,能更好的让你分清楚不同的文件的不同作用。不同的项目的组织结构都可以是相似的,下面列举了一种组织形式,大家可以参考一下。

 

  Manifest.json把所有的需要的文件都放在一起了,需要注意的一点是文件是按顺序被编译的,所以被依赖的文件往往是放在实际的script文件之前的,下面的代码中,jquery.js实在content scripts中的recorder.js和player.js之前的。  

{ "manifest_version": 2, # 插件基本信息 "name": "MyExtension", "description": "MyExtension", "version": "1.0.0", # popup弹出窗文件位置 "browser_action": { "default_icon": "img/icon.png", "default_popup": "popups/popup.html" }, # 设置 content scripts 以及什么时候注入什么类型的页面 "content_scripts": [{ "matches": ["http://*/*","https://*/*"], "css":["styles/styles.css"], "js": [ "bower_components/jquery/dist/jquery.min.js", "content-scripts/recorder.js", "content-scripts/player.js", ] }], # 设置background的scripts "background": { "scripts": [ "bower_components/jquery/dist/jquery.min.js", "bg/background.js" ] }, # 脚本的权限 "permissions": [ "<all_urls>", "tabs", "storage", "unlimitedStorage" ] }

9|0 动手做一个Chrome插件


  说了再多,不做也是没用的。我们先新建一个Manifest.json文件,复制如下代码:

{ "manifest_version": 2, "name": "GTmetrix Analyzer Plugin", "description": "This extension will analyze a page using GTmetrix", "version": "1.0", "browser_action": { "default_icon": "icon.png", "default_popup": "popup.html" }, "permissions": [ "activeTab" ] }

  其中有几点需要注意,browser_action 这个指定了点击插件的时候,弹出的页面以及 插件的图标。Permission 就是指定了哪些URL对于这个插件是有用的,比如你可以输入特定的域名,那么只有在这个域名下,这个插件才有用。

  下面我们来新建一个popup.html页面,代码如下。

<!doctype html> <html> <head> <title>GTmetrix Analyzer</title> <script src="popup.js"></script> </head> <body> <h1>GTmetrix Analyzer</h1> <button id="checkPage">Check this page now!</button> </body> </html>

  大家可能注意到了我其实使用了一个popus.js的文件,这个其实是为了实现点击checkPage时候的效果所必须的脚本,下面我们新建一个popup.js的文件。

ocument.addEventListener('DOMContentLoaded', function() { var checkPageButton = document.getElementById('checkPage'); checkPageButton.addEventListener('click', function() { chrome.tabs.getSelected(null, function(tab) { d = document; var f = d.createElement('form'); f.action = 'http://gtmetrix.com/analyze.html?bm'; f.method = 'post'; var i = d.createElement('input'); i.type = 'hidden'; i.name = 'url'; i.value = tab.url; f.appendChild(i); d.body.appendChild(f); f.submit(); }); }, false); }, false);

  细心的人不难发现,上面的代码就是向某个网站发一个post请求,checkPage其实是注册了click事件的,一旦按钮被点击了,我们就会获取到当前活动Tab并且执行一些js代码。

  那么怎么测试我们的插件呢?在Chrome地址栏输入chrome://extensions,打开开发者模式,然后点击加载已解压的扩展程序,选择相对应的目录就OK了,如果你的插件修改过,别忘了点一下重新加载(Ctrl+R)按钮。

  最终效果如下:

10|0总结


  因为Chrome插件涉及的知识点很多,所以一次也讲不完,以后如果有时间,我会把我学到的东西和大家分享,另外这个插件也是我这2天学的,因为公司要做一个信息自动刷新的功能,所以才想到了Chrome插件,不过很可惜,竞赛完了,我并没得奖,也小小吐槽下吧。


__EOF__

作  者ღKawaii
出  处https://www.cnblogs.com/kmsfan/p/5300308.html
关于博主:一个普通的小码农,为了梦想奋斗
版权声明:署名 - 非商业性使用 - 禁止演绎,协议普通文本 | 协议法律文本
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!

posted @   yangliwen  阅读(7862)  评论(7编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
3
0
关注
跳至底部
document.getElementById("homeTopTitle").innerText="ღKawaii";
点击右上角即可分享
微信分享提示