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