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

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

架构

  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,也就是说,注入操作是可选择的。

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

Manifest.json

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

Background

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

Popup

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

Content Scripts

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

Injected Scripts

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

关联关系

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

  在应用程序级别的部分是可以有互相访问的权限的。比如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插件部分。

结构

  组织你的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"
]
}

动手做一个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)按钮。

  最终效果如下:

总结

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

动手做第一个Chrome插件的更多相关文章

  1. chrome 浏览器插件开发(一)—— 创建第一个chrome插件

    最近在开发一个chrome插件,在网上找到了一些的文章,虽说按照文章可以写出对应的例子,但若要进行实际开发,发现还是有不少文章中没有的坑.下面我将结合我在开发过程中遇到的几个方面,对这些坑做一下补充. ...

  2. 开发一个chrome插件:将百度搜索热点屏蔽掉!

    每次百度搜索,搜索结果的右边总是出现些乱七八糟的搜索热点(推的都是些什么玩意,高校替课和我有毛关系,几个悲伤的热点我用星号顶掉了). 强迫症想把它隐藏掉,我用的是chrome浏览器,受adblock( ...

  3. 我的项目:一个chrome插件的诞生记,名字叫jumper

    选课是个问题,为了选课,便有了以下的故事. 最开始,萌生想法于2013年7月. 接着网上了解了chrome的结构知识,却发现例子是假的. 幸好有之前师兄的一个同功能插件开源,但代码写得很乱,我喜欢逻辑 ...

  4. 为了少点击几次,自己写了一个Chrome插件

    缘由 chrome应用商店有三款二维码插件,自己一直使用的第一款.这三款插件有且只有一个功能就是生成当前页面的URL的二维码. 其实这个功能基本上满足了需要移动端开发在微信里打开页面进行调试的情况. ...

  5. 我的第一个Chrome插件:天气预报应用

    1.Chrome插件开发基础   开发Chrome插件很简单,只要会基本的前台技术HTML.CSS.JS就可以开发了. Chrome插件一般包括两个HTML页面background和popup.   ...

  6. 做了一个jquery插件,使表格的标题列可左右拉伸

    示例下载 插件名称命名为:jquery.tableresize.js,代码如下: /* Writen by mlcactus, 2014-11-24 这是我封装的一个jquery插件,能够使table ...

  7. js写一个chrome 插件

    访问网站的时候,最烦的就是一些弹窗和广告.于是,就想着能不能在访问特定网站的时候,执行一段js脚本,去除页面的广告.于是乎,好像 chrome 插件可以实现. 这里,以 百度 的网站为例 新建 sim ...

  8. 菜鸟写的第一个chrome插件

    一.新建一个文件夹,用来放插件的代码 二.首先新建配置文件manifest.json // 开发参考:http://open.chrome.360.cn/extension_dev/overview. ...

  9. 【Chrome】Octotree Chrome插件离线安装

    插件下载地址:http://www.cnplugins.com/devtool/octotree/download.html Octotree 是国外程序员Buu Nguyen 做的一个 Chrome ...

随机推荐

  1. 谈谈DOMContentLoaded:Javascript中的domReady引入机制

    一.扯淡部分 回想当年,在摆脱写页面时js全靠从各种DEMO中copy出来然后东拼西凑的幽暗岁月之后,毅然决然地打算放弃这种处处“拿来主义”的不正之风,然后开启通往高大上的“前端攻城狮”的飞升之旅.想 ...

  2. NET Core-TagHelper实现分页标签

    这里将要和大家分享的是学习总结使用TagHelper实现分页标签,之前分享过一篇使用HtmlHelper扩展了一个分页写法地址可以点击这里http://www.cnblogs.com/wangrudo ...

  3. [WPF] Wait for a moment.

    一.控件介绍 在 WPF 中使用的等待控件,控件包括三种,普通的等待信息提示(WaitTip),进度条提示(WaitProgress),以及主程序覆盖的模拟时钟等待窗口(WaitClock),具体效果 ...

  4. maven-sprigmvc-mybatis配置

    pom.xml配置 <?xml version="1.0"?> <project xsi:schemaLocation="http://maven.ap ...

  5. DDD领域驱动设计 - 设计文档模板

    设计文档模板: 系统背景和定位 业务需求描述 系统用例图 关键业务流程图 领域语言整理,主要是整理领域中的各种术语的定义,名词解释 领域划分(分析出子域.核心域.支撑域) 每个子域的领域模型设计(实体 ...

  6. 免费公开课,讲解强大的文档集成组件Aspose,现在可报名

    课程①:Aspose.Total公开课内容:讲解全能型文档管理工具Aspose.Total主要功能及应用领域时间:2016-11-24 14:30 (暂定)报名地址:http://training.e ...

  7. Android之文件数据存储

    一.文件保存数据介绍 Activity提供了openFileOutput()方法可以用于把数据输出到文件中,具体的实现过程与在J2SE环境中保存数据到文件中是一样的.文件可用来存放大量数据,如文本.图 ...

  8. 远程连接mysql 1130错误解决方法

  9. Object是什么

    Object是什么 .Net程序员们每天都在和Object在打交道如果你问一个.Net程序员什么是Object,他可能会信誓旦旦的告诉你"Object还不简单吗,就是所有类型的基类" ...

  10. Lesson 16 A polite request

    Text If you park your car in the wrong place, a traffic policeman will soon find it. You will be ver ...