直擊現場html
摘要 最近折騰HTML5遊戲須要離線存儲功能,便把目前可用的幾種HTML5存儲方式研究了下,基於HT for Web寫了個綜合的實例,分別利用了Cookie、WebStorage、IndexedDB以及FileSystem四種本地離線存儲方式,對燃氣監控系統的表計位置、朝向、開關以及表值等信息作了CURD的存取操做。 HTML5的存儲還有一種Web SQL Database方式,雖然還有瀏覽器支持,是惟一的關係數據庫結構的存儲,但W3C以及中止對其的維護和發展,因此這裏咱們也再也不對其進行介紹:Beware. This specification is no longer in active ...
最近折騰HTML5遊戲須要離線存儲功能,便把目前可用的幾種HTML5存儲方式研究了下,基於HT for Web寫了個綜合的實例,分別利用了Cookie、WebStorage、IndexedDB以及FileSystem四種本地離線存儲方式,對燃氣監控系統的表計位置、朝向、開關以及表值等信息作了CURD的存取操做。程序員
HTML5的存儲還有一種Web SQL Database方式,雖然還有瀏覽器支持,是惟一的關係數據庫結構的存儲,但W3C以及中止對其的維護和發展,因此這裏咱們也再也不對其進行介紹:Beware. This specification is no longer in active maintenance and the Web Applications Working Group does not intend to maintain it further.web
整個示例主要就是將HT for Web的DataModel數據模型信息進行序列化和反序列化,這個過程很簡單經過dataModel.serialize()將模型序列化成JSON字符串,經過dataModel.deserialize(jsonString)將JSON字符串內存反序列化出模型信息,而存儲主要就是主要就是針對JSON字符串進行操做。chrome
先介紹最簡單的存儲方式LocalStorage,代碼以下,幾乎不用介紹就是Key-Value的簡單鍵值對存儲結構,Web Storage除了localStorage的持久性存儲外,還有針對本次回話的sessionStorage方式,通常狀況下localStorage較爲經常使用,更多可參考 http://www.w3.org/TR/webstorage/數據庫
1234567891011121314151617181920212223function
save(dataModel){
var
value = dataModel.serialize();
window.localStorage[
'DataModel'
] = value;
window.localStorage[
'DataCount'
] = dataModel.size();
console.log(dataModel.size() +
' datas are saved'
);
return
value;
}
function
restore(dataModel){
var
value = window.localStorage[
'DataModel'
];
if
(value){
dataModel.deserialize(value);
console.log(window.localStorage[
'DataCount'
] +
' datas are restored'
);
return
value;
}
return
''
;
}
function
clear(){
if
(window.localStorage[
'DataModel'
]){
console.log(window.localStorage[
'DataCount'
] +
' datas are cleared'
);
delete
window.localStorage[
'DataModel'
];
delete
window.localStorage[
'DataCount'
];
}
}
最古老的存儲方式爲Cookie,本例中我只能保存一個圖元的信息,這種存儲方式存儲內容頗有限,只適合作簡單信息存儲,存取接口設計得極其反人類,爲了介紹HTML5存儲方案的完整性我順便把他給列上:json
12345678910111213141516171819202122232425262728293031323334353637function
getCookieValue(name) {
if
(document.cookie.length > 0) {
var
start = document.cookie.indexOf(name +
"="
);
if
(start !== -1) {
start = start + name.length + 1;
var
end = document.cookie.indexOf(
";"
, start);
if
(end === -1){
end = document.cookie.length;
}
return
unescape(document.cookie.substring(start, end));
}
}
return
''
;
}
function
save(dataModel) {
var
value = dataModel.serialize();
document.cookie =
'DataModel='
+ escape(value);
document.cookie =
'DataCount='
+ dataModel.size();
console.log(dataModel.size() +
' datas are saved'
);
return
value;
}
function
restore(dataModel){
var
value = getCookieValue(
'DataModel'
);
if
(value){
dataModel.deserialize(value);
console.log(getCookieValue(
'DataCount'
) +
' datas are restored'
);
return
value;
}
return
''
;
}
function
clear() {
if
(getCookieValue(
'DataModel'
)){
console.log(getCookieValue(
'DataCount'
) +
' datas are cleared'
);
document.cookie =
"DataModel=; expires=Thu, 01 Jan 1970 00:00:00 UTC"
;
document.cookie =
"DataCount=; expires=Thu, 01 Jan 1970 00:00:00 UTC"
;
}
}
現在比較實用強大的存儲方式爲Indexed Database API,IndexedDB能夠存儲結構對象,可構建key和index的索引方式查找,目前各瀏覽器的已經逐漸支持IndexedDB的存儲方式,其使用代碼以下,需注意IndexedDB的不少操做接口相似NodeJS的異步回調方式,特別是查詢時連cursor的continue都是異步再次回調onsuccess函數的操做方式,所以和NodeJS同樣使用上不如同步的代碼容易。瀏覽器
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182request = indexedDB.open(
"DataModel"
);
request.onupgradeneeded =
function
() {
db = request.result;
var
store = db.createObjectStore(
"meters"
, {keyPath:
"id"
});
store.createIndex(
"by_tag"
,
"tag"
, {unique:
true
});
store.createIndex(
"by_name"
,
"name"
);
};
request.onsuccess =
function
() {
db = request.result;
};
function
save(dataModel){
var
tx = db.transaction(
"meters"
,
"readwrite"
);
var
store = tx.objectStore(
"meters"
);
dataModel.each(
function
(data){
store.put({
id: data.getId(),
tag: data.getTag(),
name: data.getName(),
meterValue: data.a(
'meter.value'
),
meterAngle: data.a(
'meter.angle'
),
p3: data.p3(),
r3: data.r3(),
s3: data.s3()
});
});
tx.oncomplete =
function
() {
console.log(dataModel.size() +
' datas are saved'
);
};
return
dataModel.serialize();
}
function
restore(dataModel){
var
tx = db.transaction(
"meters"
,
"readonly"
);
var
store = tx.objectStore(
"meters"
);
var
req = store.openCursor();
var
nodes = [];
req.onsuccess =
function
() {
var
res = req.result;
if
(res){
var
value = res.value;
var
node = createNode();
node.setId(value.id);
node.setTag(value.tag);
node.setName(value.name);
node.a({
'meter.value'
: value.meterValue,
'meter.angle'
: value.meterAngle
});
node.p3(value.p3);
node.r3(value.r3);
node.s3(value.s3);
nodes.push(node);
res.
continue
();
}
else
{
if
(nodes.length){
dataModel.clear();
nodes.forEach(
function
(node){
dataModel.add(node);
});
console.log(dataModel.size() +
' datas are restored'
);
}
}
};
return
''
;
}
function
clear(){
var
tx = db.transaction(
"meters"
,
"readwrite"
);
var
store = tx.objectStore(
"meters"
);
var
req = store.openCursor();
var
count = 0;
req.onsuccess =
function
(event) {
var
res = event.target.result;
if
(res){
store.
delete
(res.value.id);
res.
continue
();
count++;
}
else
{
console.log(count +
' datas are cleared'
);
}
};
}
最後是FileSystem API至關於操做本地文件的存儲方式,目前支持瀏覽器很少,其接口標準也在發展制定變化中,例如在我寫這個代碼時大部分文獻使用的webkitStorageInfo已被navigator.webkitPersistentStorage和navigator.webkitTemporaryStorage替代,存儲的文件可經過filesystem:http://www.hightopo.com/persistent/meters.txt’的URL方式在chrome瀏覽器中查找到,甚至可經過filesystem:http://www.hightopo.com/persistent/相似目錄的訪問,所以也能夠動態生成圖片到本地文件,而後經過filesystem:http:***的URL方式直接賦值給img的html元素的src訪問,所以本地存儲打開了一扇新的門,相信之後會冒出更多稀奇古怪的奇葩應用。cookie
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647navigator.webkitPersistentStorage.queryUsageAndQuota(
function
(usage, quota) {
console.log(
'PERSISTENT: '
+ usage +
'/'
+ quota +
' - '
+ usage / quota +
'%'
);
}
);
navigator.webkitPersistentStorage.requestQuota(2 * 1024 * 1024,
function
(grantedBytes) {
window.webkitRequestFileSystem(window.PERSISTENT, grantedBytes,
function
(fs) {
window.fs = fs;
});
}
);
function
save(dataModel) {
var
value = dataModel.serialize();
fs.root.getFile(
'meters.txt'
, {create:
true
},
function
(fileEntry) {
console.log(fileEntry.toURL());
fileEntry.createWriter(
function
(fileWriter) {
fileWriter.onwriteend =
function
() {
console.log(dataModel.size() +
' datas are saved'
);
};
var
blob =
new
Blob([value], {type:
'text/plain'
});
fileWriter.write(blob);
});
});
return
value;
}
function
restore(dataModel) {
fs.root.getFile(
'meters.txt'
, {},
function
(fileEntry) {
fileEntry.file(
function
(file) {
var
reader =
new
FileReader();
reader.onloadend =
function
(e) {
dataModel.clear();
dataModel.deserialize(reader.result);
console.log(dataModel.size() +
' datas are restored'
);
};
reader.readAsText(file);
});
});
return
''
;
}
function
clear() {
fs.root.getFile(
'meters.txt'
, {create:
false
},
function
(fileEntry) {
fileEntry.remove(
function
() {
console.log(fileEntry.toURL() +
' is removed'
);
});
});
}
Browser-Side的存儲方式還在快速的發展中,其實除了以上幾種外還有Application Cache,相信未來還會有新秀出現,雖然「雲」是大趨勢,但客戶端並不是要走極端的「瘦」方案,這麼多年冒出了這麼多客戶端存儲方式,說明讓客戶端更強大的市場需求是強烈的,固然目前動盪階段苦逼的是客戶端程序員,除了要適配Mouse和Touch,還要適配各類屏,現在還得考慮適配各類存儲,但願本文能在你們選型客戶端存儲方案時有點幫助,最後上段基於HT for Web操做HTML5存儲示例的視頻效果:http://v.youku.com/v_show/id_XODUzODU2MTY0.htmlsession