Chrome的更新速度能夠說前無古人,如今我天天開機的第一件事就是打開Chrome檢查是否是有了新版本。界面清爽、操做人性化、網絡備份資料和快速的啓動速度令我愛不釋手,還有它擁有衆多的擴展程序,相對於firefox的插件來講,數量上和質量上稍顯不足,但相信chrome將會很快在擴展上超越firefox,firefox上內存佔用上實在不使人滿意,也許我使用firefox的一個緣由就是由於firebug,不過相信chrome平臺的類firebug插件也會很快出現。javascript
Chrome的擴展開發十分簡單,咱們只須要掌握web開發的htm+CSS+Javascript,就能很快開發出本身的擴展。css
在開發前首先要掌握一些基礎知識。html
一、Chrome擴展文件html5
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其實是一個壓縮文件,使用解壓文件打開這個文件就能夠看到其中的文件目錄,下圖中是「關燈看視頻」擴展的截圖:java
所以能夠認爲,咱們實際上就是寫一個Web應用,而後將按照Chrome的規定將一個快捷方式放在Chrome工具欄上。web
二、Browser Actions(擴展圖標)chrome
把Browser Actions翻譯成擴展圖標不是很準確,但它的功能就是把你的應用顯示在Chrome工具欄上。咱們在上面看到一個文件manifest.json,就是使用這個文件來把相應的圖標和其餘參數註冊到Browser Actions。好比下圖中就是EverNote的擴展圖標。json
三、Page Actions(地址欄圖標)瀏覽器
若是你熟悉一些Chrome插件的話,你必定會發現有些擴展的圖標不是顯示在地址欄的右邊,而是顯示在地址內部右方,這就是Page Actions地址欄圖標。cookie
能夠看出上面中有三個Page Actions,圖中我標出的是Chrome添加書籤,如今你就會發現其實這個也是Chrome的擴展,只不是它是直接內置在Chrome的。
Page Actions與Browser Actions的區別就是Page Actions不是隨時都是顯示的,必須在特定的頁面中這個功能才能使用。所以在開發中注意:若是不是所有頁面中都能使用的功能請使用Page Actions方式。
四、popup彈出窗口
popup屬於Browser Actions,當點擊圖標時出現這個窗口,能夠在裏面放置任何html元素,它的寬度是自適應的。固然,這個彈出窗口不會被Chrome攔截的:)
以下圖中是evernote的popup窗口:
五、Background Pages後臺頁面
這個窗口不會顯示,它是擴展程序的後臺服務,它會一直保持運行。好比在一些須要數據保存程序中,若是當前用戶關閉popup,就須要Background Pages來進行相應的操做。
咱們以一個簡單的任務管理程序來一步步講解。
上圖是界面實現,咱們首先完成界面的顯示部分,首先創建一個新文件夾,以擴展應用的名稱爲標題,咱們這裏的應用叫作MyTaskList。而後把找一個圖標文件,放到文件夾中,也可直接右鍵下載個人這個圖標:
圖標文件不要小於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表明功能描述。這些在安裝擴展後就能看到,見下圖:
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裏。
首先打開Chrome-工具-擴展程序,展開開發人員模式,打到「打包擴展程序」按鈕:
點擊「打包擴展程序…」,彈出打包選擇文件窗口,在擴展程序根目標中找到咱們創建的文件夾,私有密碼文件第一次不用選擇:
點擊肯定,它會在根文件夾同一級生成MyTaskList.crx和MyTaskList.pem,MyTaskList.pem是程序簽名文件,以新版本的開發中還須要這個文件,不要刪除它。把MyTaskList.crx拖進Chrome窗體內,就會把這個應用MyTaskList安裝在Chrome裏。
咱們的這個簡單的模型就能看到效果了,下一節咱們就會完善其中的代碼。
上一節咱們已經講了Chrome擴展的基礎知識,並構建了基礎的html,這一節咱們將就html DOM添加部分添加腳本,即腳本在咱們的popup頁面中進行的操做,頁面所產生的變化。
正常狀況下數據處理加載完成狀態,這些數據是從本地數據讀取的。
點擊「添加新項」,出現輸入框,輸入文字後回車提交數據:
添加完成後將數據存儲,同時添加DOM元素:
考慮到功能最簡化處理,點擊已標爲完成的任務,將提示「刪除或重置爲未完成」:
以上功能爲最核心功能,能夠在此基礎上進行擴展,好比任務分組,修改任務,任務提醒,網絡同步數據等等。
下面開始相應的腳本內容。
爲了不全局變量,使用匿名函數方式,全部事件處理及數據綁定均在此函數中進行,同時定義與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();
})();
|
好吧,如下就是本節中所要提到的所有代碼:
代碼中還沒有實現的部分,咱們將會在下節詳細講解其實現。
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'
]=
'http://www.cnblogs.com/walkingp'
;
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等擴展開發是很是合適的。
Chrome和Safari均有本身的本地localStorage查看和管理工具,Firefox擁有第三方插件能夠管理localStorage,Chrome中位於開發人員工具中的Resources左側的Databases(可能稍早一點的版本位於單獨出來的工具欄)。咱們上面的localStorage在Chrome查看以下,利用這個工具能夠修改或者刪除相應項。
Safari中須要先在「偏好設置」、「高級」中將「在菜單中顯示開發選項」勾選。
以上是咱們須要瞭解的關於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()爲互操做。詳情可見http://json.org/js.html 。
這樣咱們就將一個簡單的Chrome擴展完成了,演示效果圖以下:
固然它如今的功能還不夠強大,咱們還能夠對它進行繼續擴展,好比任務排序、任務分組、網絡存儲、定時提醒等。
系列文章至此暫時結束,所有代碼包括生成後.crx文件已經打包,下載請點擊此處。可能已有代碼有一些處理不完善的地方,歡迎你們一一指出,共同進步!