3.5 Omnibox
Chrome和其他浏览器相比一个最大的区别就是地址栏——其实不仅仅是地址栏,而是一个多功能的输入框,Google将其称为omnibox(中文为“多功能框”)。我们熟悉的一个功能就是用户可以直接在omnibox搜索关键字,Chrome也将omnibox开放给开发者,这使得omnibox更加强大。
要使用omnibox需要在Manifest的omnibox
域指定keyword
:
"omnibox": { "keyword" : "hamster" }
同时最好指定一个16像素的图标,当用户键入关键字后,这个图标会显示在地址栏的前端。
"icons": {
"16": "icon16.png"
}
Chrome会自动将这个图标渲染成灰度图标,而无需开发者指定一个灰度的图标,由于右键菜单等其他地方也会用到16像素的图标,所以应该指定一个彩色的图标。
Omnibox只提供了一个方法,就是setDefaultSuggestion
,这个方法用来定义默认建议。对于这个默认建议用文字怎么讲解恐怕都不容易讲清楚,那么不妨来看一看设置了默认建议和不设置默认建议的对比:
未设置默认建议和设置了默认建议的对比
上图中左侧为未设置默认建议,显示为“运行 XXX 命令:XXX”,这样显然看起来不够友好。右侧则用更加友好的方式显示查询当前美元价格。
默认建议会在用户输入keyword之后一直显示在地址栏下方并且紧挨着地址栏,所以设定一个默认建议是必要的,否则简单地显示“运行 XXX 命令:XXX”会让用户摸不到头脑。
Omnibox有四种事件:onInputStarted
、onInputChanged
、onInputEntered
和onInputCancelled
,分别用于监听用户开始输入、输入变化、执行指令和取消输入行为。其中执行指令是指用户敲击回车键或用鼠标点击建议结果。
onInputStarted(function(){console.log('Input started.')});
onInputCancelled(function(){console.log('Input cancelled.')});
上面的代码执行后,用户开始输入和取消输入时,都会在控制台记录相应日志。下面我们重点来讲一讲另外两个事件。
onInputChanged
事件所承接的只有一个function类型的参数,这个function参数又有两个承接参数,第一个参数是字符串型,值为用户当前的输入值,第二个参数还是function型,用于返回建议结果,建议的结果为数组型数据,数组中的元素是建议结果对象。
chrome.omnibox.onInputChanged.addListener(function(text, suggest){
suggest([{
content: text,
description: 'Search '+text+' in Wikipedia'
}]);
});
onInputEntered
事件同样只有一个function类型的承接参数,这个function有两个承接参数,第一个是用户输入的值,字符串型,第二个是对结果的建议打开方式,字符串型,但取值范围固定。
chrome.omnibox.onInputEntered.addListener(function(text, disposition){
switch(disposition){
case 'currentTab': //do something in the current tab
break;
case 'newForegroundTab': //do something in a new tab and active it
break;
case 'newBackgroundTab': //do something in a new tab
break;
}
});
下面来制作一款实时查询美元价格的扩展。首先通过异步请求获取Yahoo上美元的价格,对这部分不熟悉的读者可以参考前面2.2节的内容。获取到数据后我们就要开始编写提供建议的函数了。
function updateAmount(amount, exchange){
amount = Number(amount);
if(isNaN(amount) || !amount){
exchange([{
'content': '$1 = ¥'+price,
'description': '$1 = ¥'+price
},{
'content': '¥1 = $'+(1/price).toFixed(6),
'description': '¥1 = $'+(1/price).toFixed(6)
}]);
}
else{
exchange([{
'content': '$'+amount+' = ¥'+(amount*price).toFixed(2),
'description': '$'+amount+' = ¥'+(amount*price).toFixed(2)
},{
'content': '¥'+amount+' = $'+(amount/price).toFixed(6),
'description': '¥'+amount+' = $'+(amount/price).toFixed(6)
}]);
}
}
var url = 'http://query.yahooapis.com/v1/public/yql?'+
'q=select%20Rate%20from%20'+
'yahoo.finance.xchange%20'+
'where%20pair%20in%20(%22USDCNY%22)&'+
'env=store://datatables.org/alltableswithkeys&'+
'format=json';
var price;
httpRequest(url, function(r){
price = JSON.parse(r);
price = price.query.results.rate.Rate;
price = Number(price);
});
chrome.omnibox.onInputChanged.addListener(updateAmount);
大家可以对照前面所讲解的部分来看这段代码,代码中的每个部分都与前面的讲解有所对应。接下来编写用户执行指令时所运行的函数。
function gotoYahoo(text, disposition){
window.open('http://finance.yahoo.com/q?s=USDCNY=X');
}
chrome.omnibox.onInputEntered.addListener(gotoYahoo);
此例中并没有理会disposition
的取值,Chrome官方也指出disposition
只是给出结果呈现的建议方式,而非必须遵循的方式,所以是否理会这个值由你自己说了算。
最后就像前面所说的那样,记得设定一个默认的建议,这样会使你的扩展看起来更加友好。
前面讲解默认建议的截图就是这个例子运行的结果,所以在此就不重复贴图了。本例的完整代码可以通过https://github.com/sneezry/chrome_extensions_and_apps_programming/tree/master/usd_price下载,载入扩展后在浏览器地址栏中输入“usd”后按空格键或Tab键就可以使用。