久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

HTML5移動應用開發第2章:移動web應用的本地存儲

在本文中,您將使用最新 Web 技術開發 Web 應用程序。這里的大多數代碼只是 HTML、JavaScript 和 CSS — 任何 Web 開發人員的核心技術。需要的最重要的東西是用于測試代碼的瀏覽器。本文中的大多數代碼將運行在最新的桌面瀏覽器上,例外的情況會指出來。當然,還必須在移動瀏覽器上進行測試,您肯定希望最新的 iPhone 和 Android SDK 支持這些代碼。本文中使用的是 iPhone SDK 3.1.3 和 Android SDK 2.1。

本地存儲基礎

Web 開發人員多年來一直在嘗試將數據存儲在客戶機上。HTTP Cookies 被濫用于此目的。開發人員將大量數據擠放在 HTTP 規范分配的 4KB 上。原因很簡單。出于各種原因,交互式 Web 應用程序需要存儲數據,并且將這些數據存儲在服務器上通常效率低下、不安全或者不適當。多年來,這個問題有了好幾種備選方法。各種各樣的瀏覽器已經引入了專有存儲 API。開發人員也利用了 Flash Player 中的擴展存儲功能(通過 JavaScript 實現)。類似地,Google 為各種瀏覽器創建了 Gears 插件,并且它包含了存儲 API。毫不奇怪的是,一些 JavaScript 庫試圖抹平這些差異。換句話說,這些庫提供一個簡單的 API,然后檢查有哪些存儲功能(可能是一個專有瀏覽器 API 或者是一個諸如 Flash 的插件)。

對 Web 開發人員來說幸運的是,HTML 5 規范最終包含了一個針對本地存儲的標準,被廣泛的瀏覽器所實現。事實上,該標準是最快被采納的標準,在所有主要瀏覽器的最新版本中都受到支持:Microsoft®、Internet Explorer®、Mozilla Firefox、Opera、Apple Safari 和 Google Chrome。對于移動開發人員更為重要的是,它在基于 WebKit 的瀏覽器(諸如 iPhone 和使用 Android(版本 2.0 或更高版本)的手機中的瀏覽器)以及其他移動瀏覽器(比如 Mozilla 的 Fennec)中受到支持。記住這一點,我們來看一下這個 API。

Storage API

localStorage API 十分簡單。實際上,根據 HTML 5 規范,它實現了 DOM Storage 接口。差別的原因是,HTML 5 指定兩個不同的對象實現該接口:localStorage 和 sessionStorage。sessionStorage 對象是一個只在會話期間存儲數據的 Storage 實現。更確切地說,只要沒有可以訪問 sessionStorage 的腳本正在運行,瀏覽器就可以刪除 sessionStorage 數據。這是與 localStorage 相對的,后者跨多個用戶會話。兩個對象共享相同的 API,所以我將只著重介紹 localStorage。

Storage API 是一種經典的名/值對數據結構。您將使用的最常見的方法是 getItem(name) 和 setItem(name, value)。這些方法完全跟您預期的一樣:getItem 返回與名稱相關聯的值,如果什么都不存在,則返回 null,而 setItem 要么是將名/值對添加到localStorage,要么是取代現有值。還有一個 removeItem(name),顧名思意,它從 localStorage 刪除一個名/值對(如果存在的話,否則什么都不做)。最后,對于在所有名/值對上迭代,存在兩個 API。一個是長度屬性,給出正在存儲的名/值對的總數。對應地,一個 key(index) 方法從存儲中使用的所有名稱中返回一個名稱。

利用這些簡單的 API,可以完成大量任務,比如說個性化或跟蹤用戶行為。這些可以說對移動 Web 開發人員是重要的用例,但是還有一個更為重要的用例:高速緩存。利用 localStorage,可以在客戶機的本地機器上容易地從服務器高速緩存數據。這讓您無需等待可能緩慢的服務器回調,并且最小化了對服務器上數據的需求量。現在來看一個例子,演示了如何使用 localStorage 來獲得這種高速緩存。

例子:利用本地存儲實現高速緩存

本例建立在本系列第 1 部分中的例子之上,那時您最先開始了 t0 開發。那個例子展示了如何通過利用地理定位 API 取得用戶的位置而執行 Twitter 的本地搜索。從那個例子開始,對它進行簡化,并大大提高它的性能。首先,將那個例子簡化成不帶地理位置的 Twitter 搜索。清單 1 展示了簡化的 Twitter 搜索應用程序。


清單 1. 最基本的 Twitter 搜索

XML/HTML Code復制內容到剪貼板
  1. <html>  
  2. <head>  
  3. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  4. <meta name = "viewport" content = "width = device-width"/>  
  5. <title>Basic Twitter Search</title>  
  6. <script type="text/javascript">  
  7.     function searchTwitter(){  
  8.         var query = "http://search.twitter.com/search.json?callback  
  9. =showResults&q=";  
  10.         query += $("kwBox").value;  
  11.         var script = document.createElement("script");  
  12.         script.src = query;  
  13.         document.getElementsByTagName("head")[0].appendChild(script);  
  14.     }  
  15.     // ui code deleted for brevity  
  16.     function showResults(response){  
  17.         var tweets = response.results;  
  18.         tweets.forEach(function(tweet){  
  19.             tweet.linkUrl = "http://twitter.com/" + tweet.from_user   
  20. + "/status/" + tweet.id;  
  21.         });  
  22.         makeResultsTable(tweets);  
  23.     }  
  24. </script>  
  25. <!--  CSS deleted for brevity -->  
  26. </head>  
  27. <body>  
  28.     <div id="main">  
  29.         <label for="kwBox">Search Twitter:</label>  
  30.         <input type="text" id="kwBox"/>  
  31.         <input type="button" value="Go!" onclick="searchTwitter()"/>  
  32.     </div>  
  33.     <div id="results">  
  34.     </div>  
  35. </body>  
  36. </html>  

在這個應用程序中,使用了 Twitter 搜索 API 對 JSONP 的支持。用戶提交搜索時,會動態添加一個腳本標記到頁面并指定回調函數的名稱,從而進行一次 API 調用。這允許您從 Web 頁面進行一次跨域調用。一旦調用返回,回調函數(showResults)就會被調用。您添加一個鏈接 URL 到 Twitter 返回的每個 tweet,然后創建一個簡單的表格用于顯示這些 tweet。為了提速,您可以高速緩存從搜索查詢得到的結果,然后在用戶每次提交查詢時使用這些緩存的結果。首先來看如何使用 localStorage 來本地存儲 tweet。

本地保存

基本的 Twitter 搜索將從 Twitter 搜索 API 提供一組 tweet。如果您可以本地保存這些 tweet,并將它們與生成它們的關鍵詞搜索相關聯,那么您就具有了一個有用的高速緩存。要保存 tweet,您只需要修改當對 Twitter 搜索 API 的調用返回時將被調用的 callback 函數。清單 2 展示了修改后的函數。


清單 2. 搜索和保存

JavaScript Code復制內容到剪貼板
  1. function searchTwitter(){  
  2.     var keyword = $("kwBox").value;  
  3.     var query = "http://search.twitter.com/search.json?callback 
  4. =processResults&q=";  
  5.     query += keyword;  
  6.     var script = document.createElement("script");  
  7.     script.src = query;  
  8.     document.getElementsByTagName("head")[0].appendChild(script);  
  9. }  
  10. function processResults(response){  
  11.     var keyword = $("kwBox").value;  
  12.     var tweets = response.results;  
  13.     tweets.forEach(function(tweet){  
  14.         saveTweet(keyword, tweet);  
  15.         tweet.linkUrl = "http://twitter.com/" + tweet.from_user + "/status/" + tweet.id;  
  16.     });  
  17.     makeResultsTable();  
  18.     addTweetsToResultsTable(tweets);  
  19. }  
  20. function saveTweet(keyword, tweet){  
  21.     // check if the browser supports localStorage  
  22.     if (!window.localStorage){  
  23.         return;  
  24.     }  
  25.     if (!localStorage.getItem("tweet" + tweet.id)){  
  26.         localStorage.setItem("tweet" + tweet.id, JSON.stringify(tweet));  
  27.     }  
  28.     var index = localStorage.getItem("index::" + keyword);  
  29.     if (index){  
  30.         index = JSON.parse(index);  
  31.     } else {  
  32.         index = [];  
  33.     }  
  34.     if (!index.contains(tweet.id)){  
  35.         index.push(tweet.id);  
  36.         localStorage.setItem("index::"+keyword, JSON.stringify(index));  
  37.     }   
  38. }  

 

從第一個函數 searchTwitter 開始。這在用戶提交搜索時被調用。相對于 清單 1 做了改動的惟一的地方是 callback 函數。不只是在 tweet 返回時顯示它們,您還需要處理它們(除了顯示,還要保存它們)。因此,您指定一個新的 callback 函數 processResults。您針對每個 tweet 調用 saveTweet。您還傳遞被用于生成搜索結果的關鍵詞。這是因為您想要將這些 tweet 與該關鍵詞相關聯。

在 saveTweet 函數中,首先進行檢查,確保 localStorage 真正受到瀏覽器的支持。正如前面所提到的,localStorage 在桌面和移動瀏覽器中都受到廣泛支持,但是在使用這樣的新特性時進行檢查總是一個好主意。如果它不受支持,那么您簡單地從函數返回。顯然不會保存任何東西,但是也不會報錯 — 應用程序在這種情況下只是不會具有高速緩存。如果 localStorage 受到支持,那么首先進行檢查,看這個 tweet 是否已經存儲。如果沒有存儲,那么使用 setItem 本地存儲它。接下來,檢索一個對應于關鍵詞的索引對象。這只是一組與關鍵詞相關聯的 tweet 的 ID。如果 tweet ID 還不是索引的一部分,那么添加它并更新索引。

注意,在 清單 3 中保存和加載 JSON 時,您使用了 JSON.stringify 和 JSON.parse。JSON 對象(或者更確切地說,是window.JSON)是 HTML 5 規范的一部分,作為一個總是存在的 原生 對象。stringify 方法將把任何 JavaScript 對象轉換成一個序列化的字符串,而 parse 方法則進行相反的操作,它從序列化的字符串表示還原 JavaScript 對象。這是很必要的,因為 localStorage只存儲字符串。但是,原生 JSON 對象并不被廣泛實現為 localStorage。例如,它不出現在 iPhone(在撰寫本文時是版本 3.1.3)的最新 Mobile Safari 瀏覽器上。它在最新 Android 瀏覽器上受支持。您可以容易地檢查它是否在那里,如果不在,就加載一個額外的 JavaScript 文件。您可以通過訪問 json.org Web 站點(參見 參考資料),獲得原生使用的相同 JSON 對象。要本地查看這些序列化的字符串是什么樣的,可以使用各種瀏覽器工具檢查 localStorage 中為給定站點存儲的內容。圖 1 展示了一些高速緩存的 tweet,它們存儲在本地,使用 Chrome 的 Developer Tools 進行查看。


圖 1. 本地高速緩存的 tweet
一系列本地高速緩存的 tweet 的屏幕截圖(帶有 Key 和 Value 字段) 

Chrome 和 Safari 都內置了開發人員工具,可以用于查看任何保存在 localStorage 中的數據。這對于調試使用 localStorage 的應用程序非常有用。它以純文本形式展示本地存儲的鍵/值對。既然您已經開始保存來自 Twitter 的搜索 API 的 tweet,以便它們可以被用作高速緩存,所以您只需開始從 localStorage 讀取它們即可。下面來看這是如何做到的。

快速本地數據加載

在 清單 2 中,您看到了一些例子使用 getItem 方法從 localStorage 讀取數據。現在當一個用戶提交搜索時,您可以檢查高速緩存命中情況,并立即加載緩存的結果。當然,您仍將針對 Twitter 搜索 API 進行查詢,因為人們一直在產生 tweet 并添加到搜索結果。但是,通過只尋找還沒在高速緩存中的結果,現在您也有了讓查詢更為高效的方式。清單 3 展示了更新后的搜索代碼。


清單 3. 首先進行本地搜索

JavaScript Code復制內容到剪貼板
  1. function searchTwitter(){  
  2.     if ($("resultsTable")){  
  3.         $("resultsTable").innerHTML = ""// clear results  
  4.     }  
  5.     makeResultsTable();  
  6.     var keyword = $("kwBox").value;  
  7.     var maxId = loadLocal(keyword);  
  8.     var query = "http://search.twitter.com/search.json?callback=processResults&q=";  
  9.     query += keyword;  
  10.     if (maxId){  
  11.         query += "&since_id=" + maxId;  
  12.     }  
  13.     var script = document.createElement("script");  
  14.     script.src = query;  
  15.     document.getElementsByTagName("head")[0].appendChild(script);  
  16. }  
  17. function loadLocal(keyword){  
  18.     if (!window.localStorage){  
  19.         return;  
  20.     }  
  21.     var index = localStorage.getItem("index::" + keyword);  
  22.     var tweets = [];  
  23.     var i = 0;  
  24.     var tweet = {};  
  25.     if (index){  
  26.         index = JSON.parse(index);  
  27.         for (i=0;i<index.length;i++){  
  28.             tweet = localStorage.getItem("tweet"+index[i]);  
  29.             if (tweet){  
  30.                 tweet = JSON.parse(tweet);  
  31.                 tweets.push(tweet);  
  32.             }  
  33.         }  
  34.     }  
  35.     if (tweets.length < 1){  
  36.         return 0;  
  37.     }  
  38.     tweets.sort(function(a,b){  
  39.         return a.id > b.id;  
  40.     });  
  41.     addTweetsToResultsTable(tweets);  
  42.     return tweets[0].id;  
  43. }  

 

您將注意到的第一件事情是,當一個搜索被提交時,您首先調用新的 loadLocal 函數。該函數返回一個整數,即高速緩存中找到的最新 tweet 的 ID。loadLocal 函數接受一個 keyword 作為參數,該關鍵詞也被用于在 localStorage 高速緩存中尋找相關 tweet。如果具有一個 maxId,那么使用它來修改對 Twitter 的查詢,添加 since_id 參數。您在告訴 Twitter API 只返回比該參數中給定的 ID 新的 tweet。潛在地,這可以減少從 Twitter 返回的結果數量。您任何時候都可以為移動 Web 應用程序優化服務器調用,因為它可以真正改善慢速移動網絡上的用戶體驗。現在更仔細地來看一下 loadLocal。

在 loadLocal 函數中,您利用了存儲在前面 清單 2 中的數據結構。通過使用 getItem,您首先加載與關鍵詞相關聯的索引。如果沒找到任何索引,那么就沒有緩存的 tweet,所以就沒有展示的東西,并且沒有可對查詢進行的優化(您返回一個 0 值以指示這一點)。如果找到一個索引,那么您從它得到 ID 列表。這些 tweet 中的每一個都被本地高速緩存,所以您只需再次使用 getItem 方法,從高速緩存加載每一個 tweet。加載的 tweet 然后被排序。使用 addTweetsToResultsTable 函數來顯示 tweet,然后返回最新 tweet 的 ID。在本例中,得到新 tweet 的 代碼直接調用更新 UI 的函數。您可能會對此感到驚訝,因為它在存儲和檢索 tweet 的代碼與顯示它們的代碼之間創建了耦合,全都通過 processResults 函數。使用存儲事件會提供一種備選的、更少耦合的方法。

存儲事件

現在擴展示例應用程序,展示最可能具有緩存結果的前 10 個搜索條目。這可能代表用戶最常提交的搜索。清單 4 展示了一個用于計算并顯示前 10 個搜索條目的函數。


清單 4. 計算前 10 個搜索條目

JavaScript Code復制內容到剪貼板
  1. function displayStats(){  
  2.     if (!window.localStorage){ return; }  
  3.     var i = 0;  
  4.     var key = "";  
  5.     var index = [];  
  6.     var cachedSearches = [];  
  7.     for (i=0;i<localStorage.length;i++){  
  8.         key = localStorage.key(i);  
  9.         if (key.indexOf("index::") == 0){  
  10.             index = JSON.parse(localStorage.getItem(key));  
  11.             cachedSearches.push ({keyword: key.slice(7), numResults: index.length});  
  12.         }  
  13.     }  
  14.     cachedSearches.sort(function(a,b){  
  15.         if (a.numResults == b.numResults){  
  16.             if (a.keyword.toLowerCase() < b.keyword.toLowerCase()){  
  17.                 return -1;  
  18.             } else if (a.keyword.toLowerCase() > b.keyword.toLowerCase()){  
  19.                 return 1;  
  20.             }  
  21.             return 0;  
  22.         }  
  23.         return b.numResults - a.numResults;  
  24.     }).slice(0,10).forEach(function(search){  
  25.         var li = document.createElement("li");  
  26.         var txt = document.createTextNode(search.keyword + " : " + search.numResults);  
  27.         li.appendChild(txt);  
  28.         $("stats").appendChild(li);  
  29.     });  
  30. }  

 

該函數充分展示了 localStorage API。您首先得到存儲在 localStorage 中的條目的總數,然后再迭代這些條目。如果條目是索引,那么您就解析該對象并創建一個表示您要處理的數據的對象:與索引相關聯的關鍵詞和索引中 tweet 的數量。該數據存儲在一個叫做cachedSearches 的數組中。接下來,排序 cachedSearches,將具有最多結果的搜索排在第一位,如果兩個搜索具有相同數量的緩存結果,就再使用一個不區分大小寫的字母排序。然后對于前 10 個搜索,為每個搜索創建 HTML,并將它們附加到一個排好序的列表。讓我們在頁面初次加載時調用該函數,如 清單 5 所示。


清單 5. 初始化頁面

				
window.onload = function() {
    displayStats();
    document.body.setAttribute("onstorage", "handleOnStorage();");
}

第一行在頁面加載時調用 清單 4 中的函數。第二次加載是變得更有趣的地方。您在這里為 onstorage 事件設置一個事件處理程序。每當 localStorage.setItem 函數執行完成,該事件就會激活。這將允許您重新計算前 10 個搜索。清單 6 展示了該事件處理程序。


清單 6. Storage 事件處理程序

				
function handleOnStorage() {
    if (window.event && window.event.key.indexOf("index::") == 0){
        $("stats").innerHTML = "";
        displayStats();
    }
}

onstorage 事件將與窗口相關聯。它具有幾個有用的屬性:key、oldValue 和 newValue。除了這些自解釋的屬性之外,它還有一個url(更改值的頁面的 URL)和 source(包含更改值的腳本的窗口)。如果用戶具有多個到應用程序的窗口或選項卡或者甚至是 iFrames,那么這最后兩個屬性就更有用,但是沒有哪一個在移動應用程序中特別常見。回到 清單 6,您真正需要的惟一的屬性是key 屬性。您使用該屬性來看它是不是一個已修改的索引。如果是的,那么您重新設置前 10 名列表,并通過再次調用 displayStats函數而重新繪制它。該技術的優點是,其他函數都不需要了解前 10 名列表,因為它是自包含的。

前面 我提到過,DOM Storage(它包含 localStorage 和 sessionStorage)總體來說是一個被廣泛采納的 HTML 5 特性。但是,存儲事件對于這一點來說是一個例外 — 至少在桌面瀏覽器上如此。在撰寫本文時,僅有的支持存儲事件的桌面瀏覽器是 Safari 4+ 和 Internet Explorer 8+。在 Firefox、Chrome 和 Opera 中不受支持。但是在移動領域,情況稍有好轉。iPhone 和 Android 瀏覽器的最新版都完全支持存儲事件,并且這里給出的代碼都能在這些瀏覽器中完美地運行。

結束語

作為一名開發人員,突然在客戶機上擁有巨額的存儲空間,您會覺得自己獲得了很大的解放。對于長期的 Web 開發人員來說,為做到他們多年來一直想做、卻苦于找不到好的方式來做的事情帶來了轉機。對于移動開發人員來說,則更為振奮人心,因為它真正開啟了數據的本地高速緩存。除了大大改善應用程序的性能之外,本地高速緩存對于推進移動 Web 應用程序的另一個新的令人振奮的功能 —— 離線 —— 是很關鍵的。這將是本系列下一篇文章的主題。

【網站聲明】本站除付費源碼經過測試外,其他素材未做測試,不保證完整性,網站上部分源碼僅限學習交流,請勿用于商業用途。如損害你的權益請聯系客服QQ:2655101040 給予處理,謝謝支持。

相關文檔推薦

這篇文章主要介紹了有關HTML5頁面在iPhoneX適配問題,需要的朋友可以參考下
本篇文章主要介紹了html5中canvas圖表實現柱狀圖的示例,本文使用canvas來實現一個圖表,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
Adobe公司出品的多媒體處理軟件產品線較多,涵蓋了音視頻編輯、圖像處理、平面設計、影視后期等領域。這篇文章主要介紹了Adobe Html5 Extension開發初體驗圖文教程,非常不錯,需要的朋
這篇文章主要介紹了基于HTML5的WebGL經典3D虛擬機房漫游動畫,需要的朋友可以參考下
這篇文章主要介紹了手機端用rem+scss做適配的詳解,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
本篇文章主要介紹了canvas 實現 github404動態效果的示例代碼,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
主站蜘蛛池模板: 1区2区视频 | 亚洲综合精品 | 美女一级毛片 | 国产亚洲网站 | 日本天堂一区二区 | 亚洲一级视频在线 | 国产成人免费视频网站高清观看视频 | 综合久久久 | 黄色在线观看国产 | 国产精品伦一区二区三级视频 | 久久亚洲天堂 | 国产一区二区三区四区hd | 国产成人免费 | 亚洲视频在线观看 | 国产视频久久久 | 久久高清 | 国产欧美一区二区三区在线看 | 粉嫩国产精品一区二区在线观看 | 国产精品欧美日韩 | 欧美a在线| 在线只有精品 | 日韩精品久久一区二区三区 | 黄色免费观看网站 | 欧美精品一二三区 | 久久久.com| 亚洲一区二区免费电影 | 中文字幕精品一区二区三区精品 | 蜜臀久久99精品久久久久野外 | 青青草网站在线观看 | 国产极品车模吞精高潮呻吟 | 秋霞av国产精品一区 | 99精品国产一区二区青青牛奶 | h视频在线看 | 91新视频 | 日本三级黄视频 | 国产免国产免费 | 欧美一区二区三区高清视频 | 精品久| 视频在线一区二区 | 女女百合av大片一区二区三区九县 | 欧美日韩在线观看一区二区三区 |