【杭州網(wǎng)站設(shè)計】HTML5本地存儲(Local Storage) 的前世今生(二)
分享 2011.07.28 瀏覽次數(shù):6876次
HTML5本地存儲(Local Storage) 的前世今生(二)
原文連接:http://diveintohtml5.org/storage.html?。ㄉ钊際TML5)
作者:Mark Pilgrim
譯者 : feijia (tiimfei@gmail.com)
這篇文章是作者的書HTML5 up & Running的的一個章節(jié),并在線以 CC-BY-3.0 License授權(quán)。
這是本文的第二部分,第一部分鏈接:
深入HTML5: HTML5 本地存儲( Local Storage )的前世今生 (一)
追蹤HTML5 存儲區(qū)域中的數(shù)據(jù)變化
除了常用的存取數(shù)據(jù)的方法,開發(fā)者還需要能夠偵測數(shù)據(jù)變化的編程接口。這就是存儲事件(storage event )
當(dāng) setItem(),removeItem()或者clear() 方法被調(diào)用,并且數(shù)據(jù)真的發(fā)生了改變時,storage事件就會被觸發(fā)。注意這里的的條件是數(shù)據(jù)真的發(fā)生了變化。也就是說,如果當(dāng)前的存儲區(qū)域是空的,你再去調(diào)用clear()是不會觸發(fā)事件的?;蛘吣阃ㄟ^setItem()來設(shè)置一個與現(xiàn)有值相同的值,事件也是不會觸發(fā)的。
所有支持localStorage對象的瀏覽器都支持存儲事件,也包括IE8。 不過由于IE8不支持W3C標(biāo)準(zhǔn)的addEventListener (IE9 支持)。因此要在不同瀏覽器中偵聽存儲事件,仍然需要一些代碼來兼顧瀏覽器之間事件處理機制的不同。
當(dāng)然你也可以使用jQuery,Dojo 或者其他Javacript類庫來幫你注冊事件處理函數(shù),存儲事件也是可以支持的。
- if (window.addEventListener) {
- window.addEventListener('storage', handle_storage, false);
- } else {
- window.attachEvent('onstorage', handle_storage);
- };
上面代碼中handle_storage 是在存儲事件發(fā)生時被調(diào)用的回調(diào)函數(shù),傳入?yún)?shù)是StorageEvent。 在IE中,該event對象會被保存在window.event 中。
- function handle_storage(e) {
- if (!e) { e = window.event; }
- }
StorageEvent對象會包含下列的屬性。
屬性 | 類型 | 描述 |
---|---|---|
key |
string | 被修改的鍵。 |
oldValue |
any | 修改前的值(如果是增加新的鍵值,則該屬性為null) |
newValue |
any | 修改后的值(如果是刪除鍵值,則該屬性為null) |
url * |
string | 觸發(fā)當(dāng)前存儲事件的頁面的url |
* 注意: url 屬性早期的規(guī)范中為uri屬性。 有些瀏覽器發(fā)布較早,沒有包含這一變更。為兼容性考慮,使用url屬性前,你應(yīng)該先檢查它是否存在,如果沒有url屬性,則應(yīng)該使用uri屬性 |
要注意一點,在存儲事件的處理函數(shù)中是不能取消這個存儲動作的。存儲事件只是瀏覽器在數(shù)據(jù)變化發(fā)生之后給你的一個通知。
目前技術(shù)的局限
前面的章節(jié)中, 我提到了過去許多用來實現(xiàn)瀏覽器本地存儲的技術(shù)和插件的缺點,例如存儲容量的限制。其實HTML5本地存儲標(biāo)準(zhǔn)也有它自身的局限。簡單來說就是這幾個關(guān)鍵詞,“5M容量'和 “QUOTA_EXCEEDED_ERR“ 。
“5M 容量',是每個來源(origin)(http://www.whatwg.org/specs/web-apps/current-work /multipage/origin-0.html#origin-0)允許存儲容量的默認(rèn)限制。在HTML5 存儲標(biāo)準(zhǔn)中,5M只不過是作為一個建議的數(shù)值出現(xiàn)的,但是這個建議被所有的瀏覽器所采用。挺奇怪的,不是嗎? 需要注意的是,存儲的數(shù)據(jù)都是以字符串形式保存的。因此如果你存儲了大量整型數(shù)或浮點數(shù),這些數(shù)也會以字符串形式保存。浮點數(shù)的每一位都需要一個字符來表示。 這大大增加了所需要的存儲空間。
第二個關(guān)鍵詞“QUOTA_EXCEEDED_ERR” 是一個異常,如果你使用的存儲容量超過了5M,你就會碰到它。
接下來你自然會要問那如果我想使用超過5M的容量,是不是可以通過彈出對話框讓用戶授權(quán)的方式來增加允許容量么?很遺憾,答案是”不行!“ 在這篇文章寫作時,(2月 2011), 沒有瀏覽器支持允許程序向用戶請求更大存儲空間的機制。 有些瀏覽器(例如Opera)允許用戶自己來控制每個站點可使用的存儲容量,但是這必須由用戶自己主動發(fā)起才行,作為開發(fā)者你沒有辦法來發(fā)起這樣的請求。
HTML5 本地存儲 實戰(zhàn)
這一節(jié)讓我們來實際操作一下HTML5 本地存儲。 回憶一下我們在canvas章節(jié)中開發(fā)的Halma 游戲。由于沒有加入本地存儲支持,每次關(guān)閉瀏覽器這個游戲的進度就會丟失。現(xiàn)在我們可以用HTML5 本地存儲技術(shù)在瀏覽器中保存玩家的游戲進度。這里是一個演示。
試試看,在游戲中操作一些步驟,然后關(guān)閉該標(biāo)簽頁然后在新標(biāo)簽頁中再打開該游戲頁面。如果你的瀏覽器支持HTML5本地存儲,你會發(fā)現(xiàn)關(guān)閉前的游戲進度和狀態(tài)被神奇的記錄下來了。
這是怎么實現(xiàn)的呢? 在游戲中,每次發(fā)生狀態(tài)變化,我們都會調(diào)用下面的方法:
- function saveGameState() {
- if (!supportsLocalStorage()) { return false; }
- localStorage['halma.game.in.progress'] = gGameInProgress;
- for (var i = 0; i < kNumPieces; i++) {
- localStorage['halma.piece.' + i + '.row'] = gPieces[i].row;
- localStorage['halma.piece.' + i + '.column'] = gPieces[i].column;
- }
- localStorage['halma.selectedpiece'] = gSelectedPieceIndex;
- localStorage['halma.selectedpiecehasmoved'] = gSelectedPieceHasMoved;
- localStorage['halma.movecount'] = gMoveCount;
- return true;
首先保存一個標(biāo)志變量”gGameInProgress'用來指示當(dāng)前是否有一個游戲正在進行。 然后是保存正在進行中的游戲的狀態(tài),包括哪些棋子被選中了,當(dāng)前一共走的總步數(shù)等等 。
在每次頁面加載時,我們會調(diào)用resumeGame()方法,這個方法會先檢查本地存儲中的halma.game.in.progress'標(biāo)志,如果是true,則會恢復(fù)上次保存的游戲狀態(tài)。如果false,則調(diào)用newGame開始新游戲。
- function resumeGame() {
- if (!supportsLocalStorage()) { return false; }
- gGameInProgress = (localStorage['halma.game.in.progress'] == 'true');
- if (!gGameInProgress) { return false; }
- gPieces = new Array(kNumPieces);
- for (var i = 0; i < kNumPieces; i++) {
- var row = parseInt(localStorage['halma.piece.' + i + '.row']);
- var column = parseInt(localStorage['halma.piece.' + i + '.column']);
- gPieces[i] = new Cell(row, column);
- }
- gNumPieces = kNumPieces;
- gSelectedPieceIndex = parseInt(localStorage['halma.selectedpiece']);
- gSelectedPieceHasMoved = localStorage['halma.selectedpiecehasmoved'] == 'true';
- gMoveCount = parseInt(localStorage['halma.movecount']);
- drawBoard();
- return true;
- }
在上面resumeGame中最重要的一點就是“ 所有HTML5 本地存儲中的數(shù)據(jù)都是以字符串形式保存的,如果你保存了其他數(shù)據(jù)類型,在訪問這些數(shù)據(jù)時一定要自己對這些數(shù)據(jù)做強制類型轉(zhuǎn)換'。 例如我們保存的標(biāo)志變量gGameInProgress是一個Boolean類型。 在saveGameState()中我們不需要做任何特別操作
- localStorage['halma.game.in.progress'] = gGameInProgress;
但是在resumeGame中,我們要訪問這個數(shù)據(jù)時,則必須做從string到Boolean的強制轉(zhuǎn)換
- gGameInProgress = (localStorage['halma.game.in.progress'] == 'true');
類似的,處理數(shù)值類型,例如gMoveCount 變量,在saveGameStat中我們用下面的語句保存一個整型變量
- localStorage['halma.movecount'] = gMoveCount;
但在resumeGame方法中,則要使用JavaScript的parseInt函數(shù)來將這個值從字符串轉(zhuǎn)換為整型
- MoveCount = parseInt(localStorage['halma.movecount']);
比鍵值對更強大的未來
相比HTML5標(biāo)準(zhǔn)成型前的混亂狀態(tài),今天HTML5本地存儲的情形前所未有的令人振奮。 新的API被標(biāo)準(zhǔn)化,并且被所有的主流瀏覽器平臺和設(shè)備所支持。 作為看慣了各種不兼容的Web程序員,很少有機會看到如此美妙一致的現(xiàn)實。 不過5M的存儲容量以及僅僅能存儲鍵值對這種簡單數(shù)據(jù)結(jié)構(gòu)對于較復(fù)雜的應(yīng)用來說仍然是遠遠不夠的。所以客戶端持久化的未來仍然有許多發(fā)展的空間。而現(xiàn)在我們已經(jīng)能看到許多互相競爭的技術(shù)在浮現(xiàn)。
其中一種技術(shù)的大名你也許早就聽到過 'SQL'. (譯者: 這句笑話很冷?。?2007年,Google發(fā)布Gears項目。Gears是一個跨瀏覽器的插件,其中就包含了一個基于SQLite的嵌入式數(shù)據(jù)庫。 這一早期原型后來影響了Web SQL DataBase 規(guī)范的建立.
WebSQLDataBase (之前也稱作 WebDB) 在SQL DB之上提供了一層簡單封裝,從而允許你在JavaScript中使用下面的代碼:
(這可不是偽代碼,下面的代碼在4個瀏覽器里是真的可以工作的?。?/em>
- openDatabase('documents', '1.0', 'Local document storage', 5*1024*1024, function (db) {
- db.changeVersion('', '1.0', function (t) {
- t.executeSql('CREATE TABLE docids (id, name)');
- }, error);
- });
這段代碼的核心就是傳入 executeSql方法的SQL 語句。這里它能夠支持所有的SQL語句,包括SELECTUPDATE, INSERT 和 DELETE。 一切都和后臺的數(shù)據(jù)庫編程沒什么區(qū)別,唯一不同的是你是在JavaScript里調(diào)用的! 太歡樂了!
Web SQL Database 標(biāo)準(zhǔn)已經(jīng)在4個瀏覽器(以及對應(yīng)的平臺)中被實現(xiàn)了。
Web SQL Database supportIE Firefox Safari Chrome Opera iPhone Android
· · 4.0+ 4.0+ 10.5+ 3.0+ 2.0+
當(dāng)然,如果你對SQL略微有所了解的話,你就會明白其實“SQL” 這個詞更多只是一個常用術(shù)語而不是一個真正統(tǒng)一的標(biāo)準(zhǔn)。( 這其實和HTML5 這個詞是一樣的 ) 當(dāng)然,我們讀書時都學(xué)過一個SQL-92 標(biāo)準(zhǔn),遺憾的是在現(xiàn)實世界里,沒有一款產(chǎn)品能真正的嚴(yán)格符合這套標(biāo)準(zhǔn)。因此我們知道有甲骨文的SQL,微軟的SQL,MySQL的SQL, PostgreSQL的SQL, SQLite的SQL。 每個廠商都在自己的數(shù)據(jù)庫產(chǎn)品中加入了特有的SQL新特性。甚至在一個廠商的產(chǎn)品中,不同的版本間SQL的用法也會產(chǎn)生變化。
這些SQL業(yè)界的紛爭就導(dǎo)致了我們看到在Web SQL Database 規(guī)范中出現(xiàn)了如下的免責(zé)聲明:
本規(guī)范現(xiàn)在碰到了一個難題: 所有的感興趣的廠商目前都使用了同樣的SQL后臺(Sqllite), 但是我們還需要有更多獨立的實現(xiàn)來使本規(guī)范成為一個標(biāo)準(zhǔn)。目前本規(guī)范中所使用的SQL語法(SQL dialect)只是一個基于Sqlite所支持的SQL語法的參考,并不會作為將來標(biāo)準(zhǔn)的一部分。
另一個與此競爭的技術(shù)是 索引數(shù)據(jù)庫(Indexed Database API ), 之前也稱作WebSimpleDB, 不過現(xiàn)在更多人叫它IndexedDB
索引數(shù)據(jù)庫API主要的概念是對象存儲容器(object store),對象存儲容器很像SQL中的數(shù)據(jù)庫概念。每個數(shù)據(jù)庫(object store)中都有很多記錄(對象),每個記錄都有很多字段(fields)。每個字段都有其預(yù)定義好的數(shù)據(jù)類型。 你可以選擇所有記錄的子集,使用游標(biāo)來遍歷所有記錄, 也提供了事務(wù)的概念來保證數(shù)據(jù)完整性和一致性。
所有這些概念都和傳統(tǒng)SQL數(shù)據(jù)庫編程很相似。最主要的區(qū)別在于,Object Store之上不能使用SQL語句這種結(jié)構(gòu)化的查詢語言。 你用不著構(gòu)建像SELECT * from USERS where ACTIVE = 'Y' 這樣的查詢。 你要做的是通過object store 提供的方法在名為USERS的數(shù)據(jù)庫上打開一個游標(biāo)指針(cursor)來遍歷所有記錄,然后過濾掉那些不滿足條件的記錄,最后在剩下的記錄上使用數(shù)據(jù)訪問方法獲取你所需要的數(shù)據(jù)。 這篇索引數(shù)據(jù)庫入門是一篇很好的教程,里面 詳細(xì)比較了索引數(shù)據(jù)庫和Web SQL 數(shù)據(jù)庫
在本文寫作時,索引數(shù)據(jù)庫只是在FF4 的beta版中被實現(xiàn)了。 Mozilla已經(jīng)聲明他們永遠不會去實現(xiàn)Web SQL 數(shù)據(jù)庫. Google 則說他們正考慮在Chromium和Google Chrome上支持索引數(shù)據(jù)庫
連微軟也說索引數(shù)據(jù)庫是'很好互聯(lián)網(wǎng)解決方案'
那么你究竟能用索引數(shù)據(jù)庫干點什么呢? 在目前的狀況下,除了一些演示之外幾乎什么也做不了。 但是誰知道1年之后會不會就大不一樣了呢。
標(biāo)簽:
杭州網(wǎng)站設(shè)計公司 杭州網(wǎng)站建設(shè)公司 杭州網(wǎng)站制作公司 杭州網(wǎng)站設(shè)計 杭州網(wǎng)站建設(shè) 杭州網(wǎng)站制作 杭州精品網(wǎng)站制作 杭州精典網(wǎng)站制作 杭州精品網(wǎng)站設(shè)計
-
杭州網(wǎng)站設(shè)計公司:品牌網(wǎng)站開發(fā)助力企業(yè)成長
日期:2024-12-20瀏覽次數(shù):595次
-
杭州網(wǎng)站建設(shè)公司:商城網(wǎng)站建設(shè)的六大關(guān)鍵步驟
日期:2024-12-18瀏覽次數(shù):627次
-
杭州網(wǎng)站制作:醫(yī)院網(wǎng)站設(shè)計與域名備案的復(fù)雜性探討
日期:2024-12-18瀏覽次數(shù):622次
-
杭州網(wǎng)站制作公司:打造安全可靠的醫(yī)院網(wǎng)站
日期:2024-12-11瀏覽次數(shù):813次
-
杭州網(wǎng)站設(shè)計公司:數(shù)據(jù)庫在高端網(wǎng)站制作中的關(guān)鍵作用
日期:2024-12-11瀏覽次數(shù):776次
相關(guān)新聞
整合同類新聞,相關(guān)新聞一手掌握
-
岳陽網(wǎng)頁設(shè)計的一些常見問題解疑
日期:2020-10-09瀏覽次數(shù):1988次
-
岳陽做網(wǎng)站:決定企業(yè)網(wǎng)站推廣走向的是什么?
日期:2020-10-09瀏覽次數(shù):1990次
最新新聞
與互聯(lián)網(wǎng)同行,實時掌握網(wǎng)建行業(yè)最新動態(tài)
-
杭州新能源網(wǎng)站建設(shè)方案
日期:2018-06-21瀏覽次數(shù):5973次
-
如何進行網(wǎng)站搭建
日期:2019-08-14瀏覽次數(shù):4649次
-
杭州小程序開發(fā)到底有什么價值?
日期:2020-12-17瀏覽次數(shù):3992次
-
直播類杭州定制小程序,成就快速變現(xiàn)之路
日期:2021-09-17瀏覽次數(shù):3774次
-
杭州網(wǎng)站優(yōu)化公司是如何提升內(nèi)容頁排名的?
日期:2024-02-23瀏覽次數(shù):4390次
隨機新聞
新聞新動態(tài),您需要的新聞管家
洞悉市場趨勢演變讓傳播回歸社會
免費獲取網(wǎng)站建設(shè)與網(wǎng)絡(luò)推廣方案報價
-
關(guān)于我們
杭州帷拓科技有限公司,是一家新型的全案網(wǎng)絡(luò)開發(fā)公司,作為以互聯(lián)網(wǎng)高端網(wǎng)站建設(shè)、APP開發(fā)、小程序開發(fā)為核心的專業(yè)網(wǎng)絡(luò)技術(shù)服務(wù)供應(yīng)商,帷拓科技致力于全面分析市場環(huán)境、衡量與預(yù)測市場需求、整合區(qū)別于行業(yè)競爭對手的絕對優(yōu)勢,結(jié)合品牌理念深度挖掘項目優(yōu)勢和產(chǎn)品價值,提升客戶品牌認(rèn)知、認(rèn)可度。
-
我們的客戶
帷拓科技?xì)v經(jīng)十年沉淀,與國內(nèi)外上千家客戶達成合作關(guān)系,其中穩(wěn)定合作的公司有:浙江華為、浙江移動、浙江5G產(chǎn)業(yè)聯(lián)盟、浙江省社科院、綠城足球俱樂部、娃哈哈雙語學(xué)校、健康中國杭州峰會、科雷機電等,帷拓科技始終堅持“帷有專業(yè),才能拓展無限”的服務(wù)理念,堅持“認(rèn)真堅持細(xì)節(jié)”的優(yōu)質(zhì)服務(wù)理念,不斷完善自身,成就企業(yè),最終實現(xiàn)共贏。
-
我們的業(yè)務(wù)
帷拓科技主營業(yè)務(wù)范圍包含互聯(lián)網(wǎng)高端網(wǎng)站建設(shè)、APP開發(fā)、小程序開發(fā)、商城網(wǎng)站建設(shè)、公眾號運營以及數(shù)字營銷等,涵蓋了服務(wù)、房產(chǎn)、數(shù)碼、服裝、物流貿(mào)易等行業(yè),根據(jù)品牌現(xiàn)狀,為每個客戶量身定制項目整體服務(wù)方案,以敏銳的市場洞察力、創(chuàng)新的市場策劃能力,全面把握市場變化,為客戶實現(xiàn)從企業(yè)到消費者的價值轉(zhuǎn)換。