--chrome交互式插件的各个部分

Chrome插件的基础知识就不多说了。随便找个新手教程就能够上手了,比如官方提供的OverviewGetting
Started
教程足够入门了;笔者也是现学现卖。

一个插件事实上就是一些常见web资源的集合,将诸如js脚本、css样式、html文本、图片甚至dll等资源打包到一个文件里,并配上一个说明文档manifest.json,来说明插件须要的权限以及各个资源之间的一些基本的关系。插件安装到浏览器之后,能够在一定程度上控制浏览器的行为,相同也能够控制浏览器中显示的web页面的dom。而使用了dll之后。插件能做的事就很多其它了。能够提供超越浏览器范畴的功能。出于安全考虑,Google官方已经在限制dll的使用。

插件中代码的划分

Chrome插件的代码大致分为三部分:

  1. background page(背景页面):大多插件包含一个不可见的背景页面,用于维持整个插件的主要逻辑。
  2. UI页面:一个插件还能够包含一些UI页面。包含弹出页面(在点击插件图标时弹出)、配置页面(配置插件时打开)以及覆盖页面(一个插件能够覆盖“书签管理页”、“历史页”或“新建标签页”三者之中的一个)。
  3. content script(内容脚本):假设插件须要跟web页面进行交互。插件就须要使用内容脚本。

插件的一个强大之处在于其与web页面交互的能力,这样的能力是通过内容脚本与页面DOM的交互来完毕的。

有了插件。一个页面的dom能够被页面本身的javascript脚本以及随意的内容脚本共享。这些脚本都能够改动页面的dom,而且全部的脚本都能够马上感知到变化,可是为了鲁棒性的考虑,web页面的脚本与内容脚本应该是互相孤立的。

各脚本执行在自己的“isolated
world(隔离世界)”中,各自包括纯净的JavaScript环境。确保相互之间不相影响

多个“隔离世界”能够共享同一个DOM树。但却分别拥有自己相应的JavaScript实现对象。

比如,web页面能够使用jQuery1.11版本号。而我们的内容脚本能够使用jQuery2.0版本号,而两者的使用互不影响。同一时候。由于插件可能拥有特权API以及用户敏感信息的訪问权限,我们须要确认web页面的脚本无法共享这些权限。由于“隔绝世界”之间不共享JavaScript对象,因此web页面的脚本不可能通过共享的DOM去打破正常的页面沙盒,来訪问内容脚本或者插件的
API。

各部分代码的交互

插件能够通过内容脚本或跨域的Ajax请求来与页面或远端服务交互。

插件中的各页面(包含背景页面)能够互相訪问各自的DOM。也能够调用各自己定义的函数。我们须要做的就是调用chrome.extension的
getViews()或getBackgroundPage()找到相应的页面,然后就能够调用其函数和操纵其DOM了。

比如我们在背景页面脚本background.js中定义了一些公用函数,如日期格式化函数:

         // (newDate()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-0208:09:04.423
// (new Date()).Format("yyyy-M-dh:m:s.S") ==> 2006-7-28:9:4.18
Date.prototype.Format = function(fmt) {
var o = {
"M+" : this.getMonth()+1, //月份
"d+" : this.getDate(), //日
"h+" : this.getHours(), //小时
"m+" : this.getMinutes(), //分
"s+" : this.getSeconds(), //秒
"q+" : Math.floor((this.getMonth()+3)/3), //季度
"S" :this.getMilliseconds() //毫秒
};
if(/(y+)/.test(fmt))
fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 -RegExp.$1.length));
for(var k in o)
if(new RegExp("("+ k+")").test(fmt))
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) :(("00"+ o[k]).substr((""+ o[k]).length)));
return fmt;
}

在弹出框的初始化脚本initPopup.js中。我们能够这样重用代码:

var bg =chrome.extension.getBackgroundPage();
Date.prototype.Format= bg.Date.prototype.Format;

内容脚本能够看作是web页面的一部分。而非插件的一部分;因此内容脚本能够改动web页面的dom,却不能够改动背景页面的dom,即不能调用getBackgroundPage等特权方法。

值得注意的是:

  • 内容脚本与web页面执行在不同的沙盒中的。两者的JS方法之间不能够相互调用。
  • 内容脚本与插件的其它部分是能够间接交互的,这一交互通过消息的收发来完毕。



消息传递

基于安全考虑,内容脚本的JavaScript环境是没有特权的。就像他影响的web页面一样。

这就意味着,假设你想要从内容脚本中訪问插件API,就必定须要一种在内容脚本与插件的特权部分进行通讯的方式,这样的方式就是“message passing(消息传递)”了。“消息传递”同意插件的各部分之间进行通讯。通常我们会希望内容脚本和背景页面之间进行通信,只是插件的随意页面之间都能够进行通讯。假设知道了其他插件的唯一ID。我们甚至能够向其他的插件发送消息。

这里举个简单的样例:

弹出框的初始化脚本中包括一个saveParam方法。负责获取弹出框中的两个值,然后存储到浏览器的同步storage中。

然后给id为btn的button设置单击事件处理函数。调用保存方法,并向插件的其它部分发送消息:

         functionsaveParam(){
_d = $('#aidForm#zcrq').val(), _hqhw = $('#aidForm #hqhw').val();
chrome.storage.sync.set({'zcrq':_d,'hqhw':_hqhw});
} function getSavedParam(callBack){
chrome.storage.sync.get(function(o){
_d = o.zcrq, _hqhw =o.hqhw;
if(null !=callBack){
callBack();
}
});
} $('#aidForm #btn').click(function(e){
saveParam();
chrome.extension.sendRequest({'msg':'openpage','zcrq':_d, 'hqhw':_hqhw,
'url':'xxxxxx'},
function(data) {});
e.preventDefault();
});

然后在背景页面脚本或内容脚本中,我们能够注冊消息监听方法。来依据消息内容进行对应的处理:

         chrome.extension.onRequest.addListener(function(request,sender, sendResponse){
if(request.msg== 'openpage'){
_d= request.zcrq, _hqhw = request.hqhw;
chrome.tabs.create({'url':request.url,'active':true});
}
});

因为内容脚本仅仅能调用chrome.extension对象中的一部分特权方法,上例中的chrome.tabs对象的特权方法即不能调用;可是内容脚本能够通过消息传递机制,发送消息给插件的其他部分,如背景页面脚本,让后者帮助其完毕部分工作。当然,有兴趣的话,插件其他部分的代码还能够使用HTML5的window.postMessage方法,配合window.addEventListener方法来进行消息的传递。

最佳实践

综上文所述,chrome插件开发的最佳实践可能是:

背景页面脚本负责维护插件的主要逻辑及方法,内容脚本负责与web页面进行直接的交互,弹出框和选项等页面作为辅助,内容脚本与插件的其他脚本之间通过消息传递机制进行交互。进而达到插件各个部分功能的融合。

That’s all! 希望能帮到大家。

另:文中一段有标了删除线的两个词“孤立”、“影响”原来各自是“duli”和“chongtu”,发表的时候竟然提示“*
对不起,文章中包括敏感词,请您检查再公布。

”。保存不成功,耽误了文章的发表,汗颜。汗颜,汗颜!

!心中奔腾着一万匹羊驼!

版权声明:本文博客原创文章,博客,未经同意,不得转载。

记得12306货运系统“抢购空”编写插件--chrome交互式插件的各个部分的更多相关文章

  1. 15款Chrome浏览器插件让设计师告别拖延症

    秋高气爽,分享一大波有效帮助设计师提高工作效率的Chrome浏览器扩展程序! 高效是另一种王道 无论是在工作中,还是在生活中,有些词我们说来就满满正能量,而另外一些话提起就很沮丧,后者如拖延症,前者如 ...

  2. 浅谈C#中一种类插件系统编写的简单方法(插件间、插件宿主间本身不需要通信)

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 三年多前还在上研时,用C#+反射机制写过插件系统,后来又用M ...

  3. Qt中如何 编写插件 加载插件 卸载插件

    Qt中如何 编写插件 加载插件 卸载插件是本文要介绍的内容.Qt提供了一个类QPluginLoader来加载静态库和动态库,在Qt中,Qt把动态库和静态库都看成是一个插件,使用QPluginLoade ...

  4. 在Qt中如何编写插件,加载插件和卸载插件(转)

    Qt提供了一个类QPluginLoader来加载静态库和动态库,在Qt中,Qt把动态库和静态库都看成是一个插件,使用QPluginLoader来加载和卸载这些库.由于在开发项目的过程中,要开发一套插件 ...

  5. 使用 jQuery UI Widget Factory 编写有状态的插件(Stateful Plugins)

    使用 jQuery UI Widget Factory 编写有状态的插件(Stateful Plugins) Note 这一章节的内容是基于 Scott Gonzalez 一篇博客 Building ...

  6. 用Javascript编写Chrome浏览器插件

    原文:http://homepage.yesky.com/62/11206062.shtml 用Javascript编写Chrome浏览器插件 2010-04-12 07:30 来源:天极网软件频道 ...

  7. [Linux实用工具]munin-node插件配置和插件编写

    前面介绍了2篇munin使用的相关文章: [Linux实用工具]Linux监控工具munin的安装和配置 [Linux实用工具]Linux监控工具munin的展示(Nginx)   这次介绍一下mun ...

  8. 编写自己的jquery插件

    如何编写自己的jquery插件 Jquery的插件主要分为三类: .封装对象方法的插件:大部分插件都是封装对象的插件 .封装全局函数的插件:将独立的函数添加到jquery的命名空间之下.Jquery. ...

  9. SpringBoot集成PageHelper时出现“在系统中发现了多个分页插件,请检查系统配置!”

    近日在项目中使用SpringBoot集成PageHelper后,跑单元测试时出现了"在系统中发现了多个分页插件,请检查系统配置!"这个问题. 如下图所示: org.mybatis. ...

随机推荐

  1. cocos2d-x学习过程中的疑问

    1.一个Scene中不同的层或者有几层Layer是在什么时候设置的? 2.helloWord中init()函数是有谁来调用的? 答:HelloWorld的init函数是在create函数调用后才会调用 ...

  2. DateTime.Compare(t1,t2)比較两个日期大小

    DateTime.Compare(t1,t2)比較两个日期大小,排前面的小,排在后面的大,比方:2011-2-1就小于2012-3-2返回值小于零:  t1 小于 t2. 返回值等于零 : t1 等于 ...

  3. ORACLE触发特定的解释

    ORACLE PL/SQL编程八: 把触发器说透 本篇主要内容例如以下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触发器 8.1.3 系统触发器 8.2 创建触发器 8.2.1 ...

  4. ASP.NET执行循序

    首先第一次运行一个应用程序(WebSite或者WebApplication都是Web应用程序)第一次请求 -> 1,IIS -> 2,aspnet_isapi(非托管dll) -> ...

  5. 返璞归真 asp.net mvc (8) - asp.net mvc 3.0 新特性之 Model

    原文:返璞归真 asp.net mvc (8) - asp.net mvc 3.0 新特性之 Model [索引页][源码下载] 返璞归真 asp.net mvc (8) - asp.net mvc ...

  6. ZOJ Problem Set - 2563 Long Dominoes 【如压力dp】

    称号:ZOJ Problem Set - 2563 Long Dominoes 题意:给出1*3的小矩形.求覆盖m*n的矩阵的最多的不同的方法数? 分析:有一道题目是1 * 2的.比較火.链接:这里 ...

  7. pragma message任务

    pragma message它是用来告诉程序猿,在编译的程序信息.和outputdebugstr则是告诉程序猿.程序在执行时期的信息. 以下就以一个样例来解说pragma message. 配合#if ...

  8. Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock’

    今天服务器遇到了一个很熟悉的问题 输入 #mysql -u root -p ERROR 2002 (HY000): Can't connect to local MySQL server throug ...

  9. 开销是有益的:AppCan 至HTML5移动创新和创业精神和健康

      2014年移动创业更趋向理性,消费级App市场接近饱和,BAT等巨头的竞争更加激烈,市场版图及格局基本定型.而企业级移动应用却迎来爆发增长,替代进入红海的消费级App市场,企业级定制APP开发成为 ...

  10. c# 判断字符是否是全角, 获取字符串的字节数 , 获取字符串指定长度字节数的字符串

    1 Encoding.Default.GetByteCount(checkString);  =2 全角 =1 半角 /// <summary> /// 获取字符串的字节长度 /// &l ...