Chrome的更新速度可以说前无古人,现在我每天开机的第一件事就是打开Chrome检查是不是有了新版本。界面清爽、操作人性化、网络备份资料和快速的启动速度令我爱不释手,还有它拥有众多的扩展程序,相对于firefox的插件来说,数量上和质量上稍显不足,但相信chrome将会很快在扩展上超越firefox,firefox上内存占用上实在不令人满意,也许我使用firefox的一个原因就是因为firebug,不过相信chrome平台的类firebug插件也会很快出现。

Chrome的扩展开发十分简单,我们只需要掌握web开发的htm+CSS+Javascript,就能很快开发出自己的扩展。

你需要了解的内容

在开发前首先要掌握一些基础知识。

1、Chrome扩展文件

Chrome扩展文件以.crx为后缀名,在Google Chrome扩展官方网站下载扩展时,Chrome会将.crx文件下载到Chrome的Application Data文件夹的User Data\Temp下,一般是C:\Documents and Settings\User\Local Settings\Application Data\Google\Chrome\User Data\Temp,安装完成或者取消安装,该文件就会被删除。.crx实际上是一个压缩文件,使用解压文件打开这个文件就可以看到其中的文件目录,下图中是“关灯看视频”扩展的截图:

Chrome拓展开发 jQuery chrome扩展开发文档_html

因此可以认为,我们实际上就是写一个Web应用,然后将按照Chrome的规定将一个快捷方式放在Chrome工具栏上。

2、Browser Actions(扩展图标)

把Browser Actions翻译成扩展图标不是很准确,但它的功能就是把你的应用显示在Chrome工具栏上。我们在上面看到一个文件manifest.json,就是使用这个文件来把相应的图标和其他参数注册到Browser Actions。比如下图中就是EverNote的扩展图标。

Chrome拓展开发 jQuery chrome扩展开发文档_Chrome拓展开发 jQuery_02

3、Page Actions(地址栏图标)

如果你熟悉一些Chrome插件的话,你一定会发现有些扩展的图标不是显示在地址栏的右边,而是显示在地址内部右方,这就是Page Actions地址栏图标。

Chrome拓展开发 jQuery chrome扩展开发文档_ide_03

可以看出上面中有三个Page Actions,图中我标出的是Chrome添加书签,现在你就会发现其实这个也是Chrome的扩展,只不是它是直接内置在Chrome的。

Page Actions与Browser Actions的区别就是Page Actions不是随时都是显示的,必须在特定的页面中这个功能才能使用。因此在开发中注意:如果不是全部页面中都能使用的功能请使用Page Actions方式。

4、popup弹出窗口

popup属于Browser Actions,当点击图标时出现这个窗口,可以在里面放置任何html元素,它的宽度是自适应的。当然,这个弹出窗口不会被Chrome拦截的:)

如下图中是evernote的popup窗口:

Chrome拓展开发 jQuery chrome扩展开发文档_Chrome_04

5、Background Pages后台页面

这个窗口不会显示,它是扩展程序的后台服务,它会一直保持运行。比如在一些需要数据保存程序中,如果当前用户关闭popup,就需要Background Pages来进行相应的操作。

自己动手做一个

我们以一个简单的任务管理程序来一步步讲解。

Chrome拓展开发 jQuery chrome扩展开发文档_html_05

上图是界面实现,我们首先完成界面的显示部分,首先建立一个新文件夹,以扩展应用的名称为标题,我们这里的应用叫做MyTaskList。然后把找一个图标文件,放到文件夹中,也可直接右键下载我的这个图标:

Chrome拓展开发 jQuery chrome扩展开发文档_ide_06

图标文件不要小于19px*19px,但最好也不要超过这个尺寸,虽然大图它会自适应,但会使得应用文件变大。然后完成和未完成状态的两个图标放到资源文件中,可以建立任意文件夹放进去,因为CSS文件把定义它们的路径。

建立manifest.json来定义我们程序配置:


{  
"name": "MyTaskList",  
"version": "0.9.0",  
"description": "Management my everyday's task lists.",  
"browser_action": {  
"default_icon": "icon.png" ,
"default_title": "My Task List",
"default_popup": "popup.html"
}  
}

其中name代表应用程序名,version代表版本号,description代表功能描述。这些在安装扩展后就能看到,见下图:

Chrome拓展开发 jQuery chrome扩展开发文档_html_07

browser_action代表扩展图标段显示,它会定义图标地址、标题(也就是鼠标悬停提示)和默认的popup页面。我们这里定义的popup页面为popup.html。

接下来开始定义popup.html显示,它不需要使用<html>、<head>和<body>标签,可以直接写上样式、脚本和html。我们的popup.html源码为:


<style type="text/css">
*{margin:0;padding:0;}
body{color:#333;overflow: hidden;margin: 0px;padding:5px;background: white;font-size:12px;}
img{margin:0 4px;}
#addItemDiv{color:#ccc;}
.hide{display:none;}
.show{display:block;}
.taskItem{cursor:pointer;}
input{width:100%;}
label.on{width:12px; display:inline-block; height:12px; background:url(images/bg_task_on.gif) no-repeat 0px 2px;}
label.off{width:12px; display:inline-block; height:12px; background:url(images/bg_task_off.gif) no-repeat 0px 2px;}
</style>
<div id="newItem" class="gray">添加新项</div>
<div id="addDiv" class="hide"><input type="text" id="txtTitle" /></div>
<div id="taskItemList">
<div class="taskItem">
<label class="on"></label><span class="taskTitle">新任务</span>
</div>
<div class="taskItem">
<label class="off"></label><span class="taskTitle">已完成任务</span>
</div>
</div>


打开预览,样子就已经出来了:

Chrome拓展开发 jQuery chrome扩展开发文档_html_08

这样我们文件就已经建立完成,文件列表如下:

Chrome拓展开发 jQuery chrome扩展开发文档_ide_09

现在就可以先尝试把它打包装到自己的Chrome里。

首先打开Chrome-工具-扩展程序,展开开发人员模式,打到“打包扩展程序”按钮:

Chrome拓展开发 jQuery chrome扩展开发文档_html_10

点击“打包扩展程序…”,弹出打包选择文件窗口,在扩展程序根目标中找到我们建立的文件夹,私有密码文件第一次不用选择:

Chrome拓展开发 jQuery chrome扩展开发文档_ide_11

点击确定,它会在根文件夹同一级生成MyTaskList.crx和MyTaskList.pem,MyTaskList.pem是程序签名文件,以新版本的开发中还需要这个文件,不要删除它。把MyTaskList.crx拖进Chrome窗体内,就会把这个应用MyTaskList安装在Chrome里。

Chrome拓展开发 jQuery chrome扩展开发文档_Chrome_12

我们的这个简单的模型就能看到效果了,下一节我们就会完善其中的代码。

上一节我们已经讲了Chrome扩展的基础知识,并构建了基础的html,这一节我们将就html DOM添加部分添加脚本,即脚本在我们的popup页面中进行的操作,页面所产生的变化。

正常情况下数据处理加载完成状态,这些数据是从本地数据读取的。

Chrome拓展开发 jQuery chrome扩展开发文档_html_13

点击“添加新项”,出现输入框,输入文字后回车提交数据:

Chrome拓展开发 jQuery chrome扩展开发文档_ide_14

添加完成后将数据存储,同时添加DOM元素:

Chrome拓展开发 jQuery chrome扩展开发文档_Chrome_15

考虑到功能最简化处理,点击已标为完成的任务,将提示“删除或重置为未完成”:

Chrome拓展开发 jQuery chrome扩展开发文档_Chrome_16

以上功能为最核心功能,可以在此基础上进行扩展,比如任务分组,修改任务,任务提醒,网络同步数据等等。

下面开始相应的脚本内容。

为了避免全局变量,使用匿名函数方式,所有事件处理及数据绑定均在此函数中进行,同时定义与jQuery中的$()类似的函数:


(function(){
var $=function(id){return document.getElementById(id);}
})();


建立Tasks对象,定义show()函数和hide()函数,同时存储几个常用的DOM对象。


var Tasks = {
show:function(obj){
obj.className='';
return this;
},
hide:function(obj){
obj.className='hide';
return this;
},
//存储dom
$addItemDiv:$('addItemDiv'),
$addItemInput:$('addItemInput'),
$txtTaskTitle:$('txtTaskTitle'),
$taskItemList:$('taskItemList')
}


其中show()函数和hide()函数均使用了链式调用,每次执行此函数均会返回对象本身,这样对象就可以使用形如类似jQuery书写方式来使用此函数。

然后注册事件:

//.....
//初始化
init:function(){
/*注册事件*/
//打开添加文本框
Tasks.$addItemDiv.addEventListener('click',function(){
Tasks.show(Tasks.$addItemInput).hide(Tasks.$addItemDiv);
Tasks.$txtTaskTitle.focus();
},true);
//回车添加
Tasks.$txtTaskTitle.addEventListener('keyup',function(ev){
var ev=ev || window.event;
if(ev.keyCode==13){
//TODO:写入本地数据
Tasks.AppendHtml(task);
Tasks.$txtTaskTitle.value='';
Tasks.hide(Tasks.$addItemInput).show(Tasks.$addItemDiv);
}
ev.preventDefault();
},true);
//取消
Tasks.$txtTaskTitle.addEventListener('blur',function(){
Tasks.$txtTaskTitle.value='';
Tasks.hide(Tasks.$addItemInput).show(Tasks.$addItemDiv);
},true);
//TODO:初始化数据,加载本地数据,生成html          
},
//....


其中待完成部分为我们下一节将重点计到的html5的本地存储功能。再定义数据操作部分,先写上空白函数:


//....
//增加
Add:function(){
//TODO
},
//修改
Edit:function(){
//TODO
},
//删除
Del:function(){
//TODO
},
//...


还需要初始化此函数使其执行并让匿名函数执行:


(function(){
var Tasks = {
//***
}
Tasks.init();
})();


好吧,以下就是本节中所要提到的全部代码:

代码中尚未实现的部分,我们将会在下节详细讲解其实现。

 

HTML5中的localStorage

localStorage与cookie类似,它是存储在客户端浏览器中的数据,它与cookie不同的一点是它没有时间限制。localStorage属于html5中的新特性,在浏览器支持localStorage统计中,Chrome4+、Firefox3.5+、IE8+、IE7兼容模式、Safari4+、Opera10.5+都是支持localStorage的。以下代码可以用于检测你的浏览器是否支持localStorage:


if(window.localStorage){
alert('你的浏览器支持localStorage!');
}else{
alert('浏览器不支持localStorage!');
}

localStorage是以key/value方式来进行存储的,并且value只能是字符串形式,如果你要使用其他数据类型,需要进行相应的转换。设置和获取localStorage方法是使用localStorage.key,或localStorage[key]的形式,如:


localStorage.myName='walkingp';
localStorage['mySite']
alert('name:' + localStorage.myName + '\rsite:' + localStorage['mySite']);


修改其值就是重新设置相应的localStorage项取值。移除其值可以将其值设为null。


localStorage['mySite']=null;


也可以使用localStorage自带方法getItem()、setItem()和removeItem()来进行相应的获取、设置和移除localStorage项。


localStorage.setItem('age','24');
var age=localStorage.getItem('age');
alert('age:' + age);//age:24
localStorage.removeItem('age');
age=localStorage.getItem('age');
alert('age? ' + age);//age? null


可以使用clear()方法来清空所有localStorage。

对于不同域的localStorage,如本地和a.com,两者不影响对方。

关于localStorage本地存储大小,有人测试结果是其他浏览器为5M,Firefox没有作限制。而cookie一般只有几K,可见localStorage非常适合做稍大一些的数据存储,当然对于Chrome等扩展开发是非常合适的。

浏览器中的localStorage管理工具

Chrome和Safari均有自己的本地localStorage查看和管理工具,Firefox拥有第三方插件可以管理localStorage,Chrome中位于开发人员工具中的Resources左侧的Databases(可能稍早一点的版本位于单独出来的工具栏)。我们上面的localStorage在Chrome查看如下,利用这个工具可以修改或者删除相应项。

Chrome拓展开发 jQuery chrome扩展开发文档_Chrome拓展开发 jQuery_17

Safari中需要先在“偏好设置”、“高级”中将“在菜单中显示开发选项”勾选。

Chrome拓展开发 jQuery chrome扩展开发文档_html_18

开始存储我们的localStorage

以上是我们需要了解的关于localStorage的知识,接下来就是把这个知识应用到我们Chrome扩展中。我们的数据存储分为两个部分,一是每项task需要存储的内容,它是以JSON的形式来存储的,形式如下:


task1:{"id":1,"task_item":"新任务","add_time":"2011-04-04T03:20:34.879Z","is_finished":false}


task1表示key项,后台的JSON表示value项。意义很简单明了,其中is_finished表示当前任务是否已完成。当更新任务状态时就是将此项取值进行相应的更改。

还要放一个指向当前任务的数据,让它充当指针的作用,这样在添加新项时就不需要查询已有task项的id了。


'Tasks:index':1


下面是我们代码的具体实现,首先开始初始化数据:


var Tasks = {
//指针
index:window.localStorage.getItem('Tasks:index'),
//初始化
init:function(){
if(!Tasks.index){
window.localStorage.setItem('Tasks:index',Tasks.index=0);
}
//初始化数据
if(window.localStorage.length-1){
var task_list=[];
var key;
for(var i=0,len=window.localStorage.length;i<len;i++){
key=window.localStorage.key(i);
if(/task:\d+/.test(key)){
task_list.push(JSON.parse(window.localStorage.getItem(key)));
}
}
for(var i=0,len=task_list.length;i<len;i++){
Tasks.AppendHtml(task_list[i]);
}
}
},
//***
}


然后是分别是增加项Add()、修改项Edit()和删除项Del()的方法:


//增加
Add:function(task){
//更新指针
window.localStorage.setItem('Tasks:index', ++Tasks.index);
task.id=Tasks.index;
window.localStorage.setItem("task:"+ Tasks.index, JSON.stringify(task));
},
//修改
Edit:function(task){
window.localStorage.setItem("task:"+ task.id, JSON.stringify(task));
},
//删除
Del:function(task){
window.localStorage.removeItem("task:"+ task.id);
},
//***


其中的JSON.stringify是JSON将Javascript数据结构转换为JSON文本的方法,它与eval()为互操作。

这样我们就将一个简单的Chrome扩展完成了,演示效果图如下:

Chrome拓展开发 jQuery chrome扩展开发文档_Chrome拓展开发 jQuery_19


当然它现在的功能还不够强大,我们还可以对它进行继续扩展,比如任务排序、任务分组、网络存储、定时提醒等。

系列文章至此暂时结束,可能已有代码有一些处理不完善的地方,欢迎大家一一指出,共同进步!