第1章初步接触Chrome扩展应用开发
认识Chrome扩展及应用
Chrome扩展更像是一个运行于本地的网站,只是它可以利用Chrome平台提供的丰富的接口,获得更加全面的信息,进行更加复杂的操作。而它的界面则使用HTML和CSS进行描述,这样的好处是可以用很短的时间构建出赏心悦目的UI。界面的渲染完全不需要开发者操心,而是交给Chrome去做。同时由于JavaScript是一门解释语言,无需对其配置编译器,调试代码时你只要刷新一下浏览器就可以看到修改后的结果,这使得开发周期大大缩短。
同时Chrome浏览器相比于Java虚拟机、Python解释器(Linux和OSX中默认安装了Python,而Windows中默认没有安装)等其他语言环境更加普及——我甚至可以在我们学校的图书馆计算机中找到Chrome浏览器——所以你所开发的Chrome扩展就可以在更多的计算机中运行。当你眼前遇到一个问题需要利用计算机去处理,而这台计算机恰好安装了Chrome浏览器,那么你就可以欢快地打开记事本开始编写程序了,之后加载到Chrome浏览器中就可以查看运行结果,这是一件多么酷的事啊!
我的第一个Chrome扩展3
Manifest文件格式
由于Google更新得非常频繁,上述页面内容可能会经常变动,但那些比较基本的属性变动的几率不会很大。
DOM简述
第2章Chrome扩展基础
操作用户正在浏览的页面
这个demo 使得用户无法点击google的搜索按钮
2.2跨域请求
functioncount(n){
varsum=0;
for(vari=1;i<=n;i++){
sum+=i;}
return sum;
}
varc=count(5)+1;
console.log(c);
上面这个例子会在控制台显示16,因为count(5)=1+2+3+4+5=15,c=15+1=16。我们再看下面的例子:
functionhttpRequest(url){
var xhr=newXMLHttpRequest();xhr.open("GET",url,true);
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
return xhr.responseText;
}
}
xhr.send();
}
varhtml=httpRequest('test.txt');console.log(html);
上例运行结果
通过上图可以发现,虽然请求的资源内容为HelloWorld!,但却并没有正确地显示出来。对于第一个例子,count函数是一个阻塞函数,在它没有运行完之前它会阻塞下面的代码运行,所以直到count计算结束后才将结果返回后再加1赋给变量c,最后将变量c的值打印出来。而第二个例子中的httpRequest函数不是一个阻塞函数,在它没运行完之前后面的代码就已经开始运行,这样html变量在httpRequest函数没返回值之前就被赋值,所以最终的结果必然就是undefined了。
常驻后台
Chrome允许扩展应用在后台常驻一个页面以实现这样的功能。在一些典型的扩展中,UI页面,如popup页面或者options页面,在需要更新一些状态时,会向后台页面请求数据,而当后台页面检测到状态发生改变时,也会通知UI界面刷新。
在Manifest中指定background域可以使扩展常驻后台。background可以包含三种属性,分别是scripts、page和persistent。通常使用scripts。
带选项页面的扩展
var city = localStorage.city;
city = city?city:'beijing';
document.getElementById('city').value = city;
document.getElementById('save').onclick = function(){
localStorage.city = document.getElementById('city').value;
alert('保存成功。');
}
2.跨域名异步访问天气网站
function httpRequest(url, callback){
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
callback(xhr.responseText);
}
}
xhr.send();
}
function showWeather(result){
result = JSON.parse(result);
var list = result.list;
var table = '<table><tr><th>日期</th><th>天气</th><th>最低温度</th><th>最高温度</th></tr>';
for(var i in list){
var d = new Date(list[i].dt*1000);
table += '<tr>';
table += '<td>'+d.getFullYear()+'-'+(d.getMonth()+1)+'-'+d.getDate()+'</td>';
table += '<td>'+list[i].weather[0].description+'</td>';
table += '<td>'+Math.round(list[i].temp.min-273.15)+' °C</td>';
table += '<td>'+Math.round(list[i].temp.max-273.15)+' °C</td>';
table += '</tr>';
}
table += '</table>';
document.getElementById('weather').innerHTML = table;
}
var city = localStorage.city;
city = city?city:'beijing';
var url = 'http://api.openweathermap.org/data/2.5/forecast/daily?q='+city+',china&lang=zh_cn';
httpRequest(url, showWeather);
扩展页面间的通信
有时需要让扩展中的多个页面之间,或者不同扩展的多个页面之间相互传输数据,以获得彼此的状态。比如音乐播放器扩展,当用户鼠标点击popup页面中的音乐列表时,popup页面应该将用户这个指令告知后台页面,之后后台页面开始播放相应的音乐。
Chrome提供了4个有关扩展页面间相互通信的接口,分别是runtime.sendMessage、runtime.onMessage、runtime.connect和runtime.onConnect。做为一部入门级教程,此节将只讲解runtime.sendMessage和runtime.onMessage接口,runtime.connect和runtime.onConnect做为更高级的接口请读者依据自己的兴趣自行学习,你可以在http://developer.chrome.com/extensions/extension得到有关这两个接口的完整官方文档。
储存数据
一个程序免不了要储存数据,对于Chrome扩展也是这样。通常Chrome扩展使用以下三种方法中的一种来储存数据:第一种是使用HTML5的localStorage,这种方法在上一节的内容中已经涉及(天气预报demo,暂存用户输入的城市);第二种是使用Chrome提供的存储API;第三种是使用WebSQLDatabase。
第3章Chrome扩展的UI界面
前两章我们所设计的扩展,使用的UI设计都非常简单。对于一个面向用户的产品,这样显然是不合适的。用户对一个程序的第一印象就是UI的设计,拙劣的UI设计完全可能将90%的用户挡在门外——即使功能设计得非常完美。
本章将专门讲解Chrome扩展的UI界面,通过Chrome提供丰富的界面API,我们可以设计出交互出色的扩展。
CSS简述
BrowserActions
在manifest中配置。
BrowserActions将扩展图标置于Chrome浏览器工具栏中,地址栏的右侧。如果声明了popup页面,当用户点击图标时,在图标的下侧会打开这个页面1。同时图标上面还可以附带badge——一个带有显示有限字符空间的区域——用以显示一些有用的信息,如未读邮件数、当前音乐播放时间等。
右键菜单
当用户在网页中点击鼠标右键后,会唤出一个菜单,在上面有复制、粘贴和翻译等选项,为用户提供快捷便利的功能。Chrome也将这里开放给了开发者,也就是说我们可以把自己所编写的扩展功能放到右键菜单中。
要将扩展加入到右键菜单中,首先要在Manifest的permissions域中声明contextMenus权限。
桌面提醒
之前的章节提到过利用标题和badge向用户提供有限的信息,那么如果需要向用户提供更加丰富的信息怎么办呢?Chrome提供了桌面提醒功能,这个功能可以为用户提供更加丰富的信息。
桌面提醒,图片来自http://developer.chrome.com
要使用桌面提醒功能,需要在Manifest中声明notifications权限。
Omnibox
Chrome和其他浏览器相比一个最大的区别就是地址栏——其实不仅仅是地址栏,而是一个多功能的输入框,Google将其称为omnibox(中文为“多功能框”)。我们熟悉的一个功能就是用户可以直接在omnibox搜索关键字,Chrome也将omnibox开放给开发者,这使得omnibox更加强大。
要使用omnibox需要在Manifest的omnibox域指定
keyword:"omnibox":{"keyword":"hamster"
PageActions
PageActions与BrowserActions非常类似,除了PageActions没有badge外,其他BrowserActions所有的方法PageActions都有。另外的区别就是,PageActions并不像BrowserActions那样一直显示图标,而是可以在特定标签特定情况下显示或隐藏,所以它还具有独有的show
和hide方法。