摘要:離線應用與客戶端存儲離線檢測定義了屬性來檢測設備是在線還是離線。應用緩存還有很多相關的事件,表示其狀態的改變。
離線應用與客戶端存儲 離線檢測
HTML5定義了navigator.onLine屬性來檢測設備是在線還是離線。這個屬性為true表示設備能上網,值為false表示設備離線。這個屬性的關鍵是瀏覽器必須知道設備能否訪問網絡,從而返回正確的值
不同瀏覽器之間有小差異
IE6+和Safari5+能夠正確檢測到網絡已經斷開,并將navigator.onLine的值轉換為false
Firefox3+和Opera10.6+支持navigator.onLine屬性,但必須手工選中菜單項脫機工作才能讓瀏覽器正常工作
Chrome11以及之前版本始終將navigator.onLine屬性設置為true
為了更好確定網絡是否可用,HTML5還定義了兩個事件onLine和offLine。當網絡從離線變為在線或者從在線變為離線時,分別觸發這兩個事件
EventUtil.addHandler(window, "online", function(){ alert("Online"); }); EventUtil.addHandler(window, "offline", function(){ alert("Offline"); });應用緩存
applicationCache 對象,status屬性,屬性的值是常量,表示應用緩存的如下當前狀態。
0,無緩存,即沒有與頁面相關的應用緩存。
1,閑置,即應用緩存未得到更新。
2,檢查中,即正在下載描述文件并檢查更新。
3,下載中,即應用緩存正在下載描述文件中指定的資源。
4,更新完成,即應用緩存已經更新了資源,而且所有資源都已下載完畢,可以通過 swapCache()來使用了。
5,廢棄,即應用緩存的描述文件已經不存在了,因此頁面無法再訪問應用緩存。
應用緩存還有很多相關的事件,表示其狀態的改變。以下是這些事件。
checking,在瀏覽器為應用緩存查找更新時觸發。
error,在檢查更新或下載資源期間發生錯誤時觸發。
noupdate,在檢查描述文件發現文件無變化時觸發。
downloading,在開始下載應用緩存資源時觸發。
progress,在文件下載應用緩存的過程中持續不斷地觸發。
updateready,在頁面新的應用緩存下載完畢且可以通過 swapCache() 使用時觸發。
cached,在應用緩存完整可用時觸發。
數據存儲 Cookiecookie在性質上是綁定在特定的域名下的。當設定了一個cookie后,再給創建它的域名發送請求時都會包含這個cookie。這個限制確保了儲存在cookie中的信息只能讓批準的接受者訪問,而無法被其他域訪問
cookie由瀏覽器保存的幾部分組成
名稱,一個唯一確定 cookie 的名稱。cookie 名稱是不區分大小寫的,所以 myCookie 和 MyCookie被認為是同一個 cookie。然而,實踐中最好將 cookie 名稱看作是區分大小寫的,因為某些服務器會這樣處理 cookie。cookie 的名稱必須是經過 URL 編碼的。
值,儲存在 cookie 中的字符串值。值必須被 URL 編碼。
域,cookie 對于哪個域是有效的。所有向該域發送的請求中都會包含這個 cookie 信息。這個值可以包含子域(subdomain,如 www.wrox.com ),也可以不包含它(如. wrox.com ,則對于wrox.com的所有子域都有效)。如果沒有明確設定,那么這個域會被認作來自設置 cookie 的那個域。
路徑,對于指定域中的那個路徑,應該向服務器發送 cookie。例如,你可以指定 cookie 只有從http://www.wrox.com/books/ 中才能訪問,那么 http://www.wrox.com 的頁面就不會發
送 cookie 信息,即使請求都是來自同一個域的。
失效時間,表示 cookie 何時應該被刪除的時間戳(也就是,何時應該停止向服務器發送這個cookie)。默認情況下,瀏覽器會話結束時即將所有 cookie 刪除;不過也可以自己設置刪除時間。這個值是個 GMT 格式的日期(Wdy, DD-Mon-YYYY HH:MM:SS GMT),用于指定應該刪除cookie 的準確時間。因此,cookie 可在瀏覽器關閉后依然保存在用戶的機器上。如果你設置的失效日期是個以前的時間,則 cookie 會被立刻刪除。
安全標志,指定后,cookie 只有在使用 SSL 連接的時候才發送到服務器。例如,cookie 信息只能發送給https://www.wrox.com ,而 http://www.wrox.com 的請求則不能發送 cookie。
基本的cookie操作有3種:讀取、寫入和刪除
//設置 cookie CookieUtil.set("name", "Nicholas"); CookieUtil.set("book", "Professional JavaScript"); //讀取 cookie 的值 alert(CookieUtil.get("name")); //"Nicholas" alert(CookieUtil.get("book")); //"Professional JavaScript" //刪除 cookie CookieUtil.unset("name"); CookieUtil.unset("book") //設置 cookie,包括它的路徑、域、失效日期 CookieUtil.set("name", "Nicholas", "/books/projs/", "www.wrox.com", new Date("January 1, 2010")); //刪除剛剛設置的 cookie CookieUtil.unset("name", "/books/projs/", "www.wrox.com"); //設置安全的 cookie CookieUtil.set("name", "Nicholas", null, null, null, true);
確保刪除cookie
//設置 cookie CookieUtil.set("name", "Nicholas"); CookieUtil.set("book", "Professional JavaScript"); //讀取 cookie 的值 alert(CookieUtil.get("name")); //"Nicholas" alert(CookieUtil.get("book")); //"Professional JavaScript" //刪除 cookie CookieUtil.unset("name"); CookieUtil.unset("book") //設置 cookie,包括它的路徑、域、失效日期 CookieUtil.set("name", "Nicholas", "/books/projs/", "www.wrox.com", new Date("January 1, 2010")); //刪除剛剛設置的 cookie CookieUtil.unset("name", "/books/projs/", "www.wrox.com"); //設置安全的 cookie CookieUtil.set("name", "Nicholas", null, null, null, true);
子cookie一般以查詢字符串的格式進行格式化。然后這些值可以使用單個cookie進行存儲和訪問,而非對每個名稱-值對兒使用不同的cookie存儲
要獲得一個子cookie,首先要遵循與獲得cookie一樣的基本步驟,但是在解碼cookie值之前,需要按下面方法找出子cookie信息
var SubCookieUtil = { get: function (name, subName){ var subCookies = this.getAll(name); if (subCookies){ return subCookies[subName]; } else { return null; } }, getAll: function(name){ var cookieName = encodeURIComponent(name) + "=", cookieStart = document.cookie.indexOf(cookieName), cookieValue = null, cookieEnd, subCookies, i, parts, result = {}; if (cookieStart > -1){ cookieEnd = document.cookie.indexOf(";", cookieStart); if (cookieEnd == -1){ cookieEnd = document.cookie.length; } cookieValue = document.cookie.substring(cookieStart + cookieName.length, cookieEnd); if (cookieValue.length > 0){ subCookies = cookieValue.split("&"); for (i=0, len=subCookies.length; i < len; i++){ parts = subCookies[i].split("="); result[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); } return result; } } return null; }, //省略了更多代碼 };
要設置子cookie,也有兩種方法set()和setAll()
var SubCookieUtil = { set: function (name, subName, value, expires, path, domain, secure) { var subcookies = this.getAll(name) || {}; subcookies[subName] = value; this.setAll(name, subcookies, expires, path, domain, secure); }, setAll: function(name, subcookies, expires, path, domain, secure){ var cookieText = encodeURIComponent(name) + "=", subcookieParts = new Array(), subName; for (subName in subcookies){ if (subName.length > 0 && subcookies.hasOwnProperty(subName)){ subcookieParts.push(encodeURIComponent(subName) + "=" + encodeURIComponent(subcookies[subName])); } } if (cookieParts.length > 0){ cookieText += subcookieParts.join("&"); if (expires instanceof Date) { cookieText += "; expires=" + expires.toGMTString(); } if (path) { cookieText += "; path=" + path; } if (domain) { cookieText += "; domain=" + domain; } if (secure) { cookieText += "; secure"; } } else { cookieText += "; expires=" + (new Date(0)).toGMTString(); } document.cookie = cookieText; }, //省略了更多代碼 };
為了刪除一個子cookie,首先必須獲得包含在某個cookie中的所有子cookie,然后僅刪除需要刪除的那個子cookie,然后再將余下的子cookie的值保存為cookie的值
var SubCookieUtil = { //這里省略了更多代碼 unset: function (name, subName, path, domain, secure){ var subcookies = this.getAll(name); if (subcookies){ delete subcookies[subName]; this.setAll(name, subcookies, null, path, domain, secure); } }, unsetAll: function(name, path, domain, secure){ this.setAll(name, null, new Date(0), path, domain, secure); } };IE用戶數據
一旦元素使用了userData行為,那么就可以使用setAttribute()方法在上面保存數據了,為了將數據提交到瀏覽器緩存中,還必須調用save()方法,并告訴它要保存的數據空間的名字
var dataStore = document.getElementById("dataStore"); dataStore.setAttribute("name", "Nicholas"); dataStore.setAttribute("book", "Professional JavaScript"); dataStore.save("BookInfo")Web存儲機制 Storage類型
Storage的實例與其他對象類似
clear(),刪除所有值,Firefox中沒有實現
getItem(name),根據指定的名字name獲取對應的值
key(index),獲得index位置處的值的名字
removeItem(name),刪除由name指定的名值對兒
setItem(name,value),為指定的name設置一個對應的值
sessionStorage對象
可以使用setItem()或者直接設置新的屬性類存儲數據
//使用方法存儲數據 sessionStorage.setItem("name", "Nicholas"); //使用屬性存儲數據 sessionStorage.book = "Professional JavaScript";
sessionStroage中有數據時,可以使用getItem()或者通過直接訪問屬性名來獲取數據
//使用方法讀取數據 var name = sessionStorage.getItem("name"); //使用屬性讀取數據 var book = sessionStorage.book;globalStorage對象
可以通過方括號標記使用屬性來實現
//保存數據 globalStorage["wrox.com"].name = "Nicholas"; //獲取數據 var name = globalStorage["wrox.com"].name;localStorage對象
可以像使用sessionStorage一樣來使用
//使用方法存儲數據 localStorage.setItem("name", "Nicholas"); //使用屬性存儲數據 localStorage.book = "Professional JavaScript"; //使用方法讀取數據 var name = localStorage.getItem("name"); //使用屬性讀取數據 var book = localStorage.book;storage事件
對Storage對象進行任何修改,都會在文檔上觸發storage事件,當通過屬性或setItem()方法保存數據,使用delete操作符或removeItem()刪除數據,或者調用clear()方法時,都會發生這個事件,這個事件的event對象有以下屬性
domain,發生變化的存儲空間的域名
key,設置或者刪除的鍵名
newValue,如果是設置值,則是新值,如果嘶吼刪除鍵,則是null
oldValue,鍵被更改之前的值
IndexedDB 數據庫IndexedDB最大的特色就是使用對象保存數據,而不是使用表來保存數據
使用IndexedDB第一步是打開它,將要打開的數據庫名傳給indexedDB.open()。如果傳入的數據庫已經存在,就會發送一個打開它的請求,如果傳入的數據庫不存在,就發送一個創建并打開它的請求
var request, database; request = indexedDB.open("admin"); request.onerror = function(event){ alert("Something bad happened while trying to open: " + event.target.errorCode); }; request.onsuccess = function(event){ database = event.target.result; }
可能的錯誤碼
IDBDatabaseException.UNKNOWN_ERR (1),意外錯誤,無法歸類。
IDBDatabaseException.NON_TRANSIENT_ERR (2),操作不合法。
IDBDatabaseException.NOT_FOUND_ERR (3),未發現要操作的數據庫。
IDBDatabaseException.CONSTRAINT_ERR (4),違反了數據庫約束。
IDBDatabaseException.DATA_ERR (5),提供給事務的數據不能滿足要求。
IDBDatabaseException.NOT_ALLOWED_ERR (6),操作不合法。
IDBDatabaseException.TRANSACTION_INACTIVE_ERR (7),試圖重用已完成的事務。
IDBDatabaseException.ABORT_ERR (8),請求中斷,未成功。
IDBDatabaseException.READ_ONLY_ERR (9),試圖在只讀模式下寫入或修改數據。
IDBDatabaseException.TIMEOUT_ERR (10),在有效時間內未完成操作。
IDBDatabaseException.QUOTA_ERR (11),磁盤空間不足
IndexedDB沒有版本號,一開始為數據庫指定一個版本號,可以調用setVersion()方法,傳入以字符串形式表示的版本號
if (database.version != "1.0"){ request = database.setVersion("1.0"); request.onerror = function(event){ alert("Something bad happened while trying to set version: " + event.target.errorCode); }; request.onsuccess = function(event){ alert("Database initialization complete. Database name: " + database.name + ", Version: " + database.version); }; } else { alert("Database already initialized. Database name: " + database.name + ", Version: " + database.version); }對象存儲空間
如果想驗證請求是否成功完成,可以把返回的請求對象保存在一個變量中,然后再指定onerror或onsuccess事件處理程序
//users 中保存著一批用戶對象 var i=0, request, requests = [], len = users.length; while(i < len){ request = store.add(users[i++]); request.onerror = function(){ // 處理錯誤 }; request.onsuccess = function(){ // 處理成功 }; requests.push(request); }事務
事務對象本身也有事件處理程序:onerror和oncomplete
transaction.onerror = function(event){ //整個事務都被取消了 }; transaction.oncomplete = function(event){ //整個事務都成功完成了 };使用游標查詢
實例有幾個屬性
direction,數值,表示游標移動的方向。默認值為 IDBCursor.NEXT (0),表示下一項。IDBCursor.NEXT_NO_DUPLICATE (1)表示下一個不重復的項, IDBCursor.PREV (2)表示前一項,而 IDBCursor.PREV_NO_DUPLICATE 表示前一個不重復的項。
key,對象的鍵。
value,實際的對象。
primaryKey,游標使用的鍵。可能是對象鍵,也可能是索引鍵
調用update()方法可以指定的對象更新當前游標的value,與其他操作一樣,調用update()方法也會創建一個新的請求
request.onsuccess = function(event){ var cursor = event.target.result, value, updateRequest; if (cursor){ //必須要檢查 if (cursor.key == "foo"){ value = cursor.value; // 取得當前的值 value.password = "magic!"; // 更新密碼 updateRequest = cursor.update(value); // 請求保存更新 updateRequest.onsuccess = function(){ // 處理成功 }; updateReqeust.onerror = function(){ // 處理失敗 }; } } };
調用delete()方法,會刪除相應的記錄
request.onsuccess = function(event){ var cursor = event.target.result, value, deleteRequest; if (cursor){ //必須要檢查 if (cursor.key == "foo"){ deleteRequest = cursor.delete(); // 請求刪除當前項 deleteRequest.onsuccess = function(){ // 處理成功 }; deleteRequest.onerror = function(){ // 處理失敗 }; } } };
默認情況下,每個游標只發起一次請求,要想發起另一次請求,必須調用下面的方法
continue(key),移動到結果集中的下一項。參數 key 是可選的,不指定這個參數,游標移動到下一項;指定這個參數,游標會移動到指定鍵的位置。
advance(count),向前移動 count 指定的項數。
鍵范圍
先聲明一個本地的類型
var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange;
四種方式
使用only()方法
var onlyRange = IDBKeyRange.only("007");
指定結果集的下界
//從鍵為"007"的對象開始,然后可以移動到最后 var lowerRange = IDBKeyRange.lowerBound("007"); //如果你想忽略鍵為 "007" 的對象,從它的下一個對象開始,那么可以傳入第二個參數 true //從鍵為"007"的對象的下一個對象開始,然后可以移動到最后 var lowerRange = IDBKeyRange.lowerBound("007", true);
指定結果集的上界
//從頭開始,到鍵為"ace"的對象為止 var upperRange = IDBKeyRange.upperBound("ace"); //如果你不想包含鍵為指定值的對象,同樣,傳入第二個參數 true //從頭開始,到鍵為"ace"的對象的上一個對象為止 var upperRange = IDBKeyRange.upperBound("ace", true);
同時指定結果集的上界下界。這個方法接收4個參數:表示下界的鍵、表示上界的鍵、可選的表示是否跳過下界的布爾值、可選的表示是否跳過上界的布爾值
//從鍵為"007"的對象開始,到鍵為"ace"的對象為止 var boundRange = IDBKeyRange.bound("007", "ace"); //從鍵為"007"的對象的下一個對象開始,到鍵為"ace"的對象為止 var boundRange = IDBKeyRange.bound("007", "ace", true); //從鍵為"007"的對象的下一個對象開始,到鍵為"ace"的對象的上一個對象為止 var boundRange = IDBKeyRange.bound("007", "ace", true, true); //從鍵為"007"的對象開始,到鍵為"ace"的對象的上一個對象為止 var boundRange = IDBKeyRange.bound("007", "ace", false, true)索引
要創建索引,首先引用對象存儲空間,然后調用createIndex()方法
var store = db.transaction("users").objectStore("users"), index = store.createIndex("username", "username", { unique: false });
索引上調用openCursor()方法可以創建新的游標,除了將來會把索引鍵而非主鍵保存在event.result.key屬性中之外,這個游標與在對象存儲空間上調用openCursor()返回的游標完全一樣
var store = db.transaction("users").objectStore("users"), index = store.index("username"), request = index.openCursor(); request.onsuccess = function(event){ //處理成功 };
索引上也能創建一個特殊的只返回每條記錄主鍵的游標,調用openKeyCursor()方法,這個方法接收的參數與openCursor()相同
var store = db.transaction("users").objectStore("users"), index = store.index("username"), request = index.openKeyCursor(); request.onsuccess = function(event){ //處理成功 // event.result.key 中保存索引鍵,而 event.result.value 中保存主鍵 };
使用get()方法能夠從索引中取得一個對象
var store = db.transaction("users").objectStore("users"), index = store.index("username"), request = index.get("007"); request.onsuccess = function(event){ //處理成功 }; request.onerror = function(event){ //處理失敗 };
要根據給定的索引鍵取得主鍵,可以使用getKey()方法
var store = db.transaction("users").objectStore("users"), index = store.index("username"), request = index.getKey("007"); request.onsuccess = function(event){ //處理成功 //event.result.key 中保存索引鍵,而 event.result.value 中保存主鍵 }
通過IDBIndex對象的屬性可以獲得有關索引的相關信息
name,索引的名字
keyPath,傳入createIndex()中的屬性路徑
objectStore,索引的對象存儲空間
unique,表示索引鍵是否唯一的布爾值
下面代碼可以知道根據存儲的對象建立了哪些索引
var store = db.transaction("users").objectStore("users"), indexNames = store.indexNames, index, i = 0, len = indexNames.length; while(i < len){ index = store.index(indexNames[i++]); console.log("Index name: " + index.name + ", KeyPath: " + index.keyPath + ", Unique: " + index.unique); }并發問題
剛打開數據庫時,要記著指定 onversionchange 事件處理程序。當同一個來源的另一個標簽頁調
用 setVersion() 時,就會執行這個回調函數。處理這個事件的最佳方式是立即關閉數據庫,從而保證
版本更新順利完成
var request, database; request = indexedDB.open("admin"); request.onsuccess = function(event){ database = event.target.result; database.onversionchange = function(){ database.close(); }; }限制
IndexedDB數據庫只能由同源頁面操作,因此不能跨域共享信息
每個來源的數據庫占用的磁盤空間有限制
不允許本地文件訪問IndexedDB
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/98195.html
摘要:應用緩存的應用緩存,或者簡稱為,是專門為開發離線應用而設計的。應用緩存還有很多相關的事件,表示其狀態的改變。數據存儲,通常直接叫做,最初是在客戶端用于存儲會話信息的。也就是使用值來存儲多個名稱值對兒。 所謂Web離線應用,就是在設備不能上網的情況下仍然可以運行的應用。開發離線Web應用需要幾個步驟:(1)確保應用知道設備是否能上網;(2)應用還必須能訪問一定的資源(圖像、JavaScr...
摘要:離線檢測含義設備能否上網代碼注和,和最新的沒問題應用緩存緩存的目的是專門為網頁離線設計的,當然在在線情況也會緩存機制當用戶在地址輸入請求的地址去請求網頁時,瀏覽器會先本地緩存中查看是否有對應的緩存文件,如果有然后查看新鮮度就是是否過期了,如 23.1 離線檢測 含義:設備能否上網 代碼: navigator.onLine 注:IE6+和safari+5,firefox3+和ope...
摘要:基本概念語法區分大小寫,中的一切變量函數名和操作符都區分大小寫。要將一個值轉換成對應的值,可以調用類型包括整數和浮點數值,基本數值字面量格式是十進制整數,除了十進制外還有八進制十六進制。八進制第一位必須是,十六進制第一位必須是。 基本概念 語法 區分大小寫,ECMAScript中的一切(變量、函數名和操作符)都區分大小寫。函數名不能使用typeof,因為它是一個關鍵字,但typeOf...
閱讀 1588·2019-08-30 13:18
閱讀 1578·2019-08-29 12:19
閱讀 2094·2019-08-26 13:57
閱讀 4137·2019-08-26 13:22
閱讀 1179·2019-08-26 10:35
閱讀 2991·2019-08-23 18:09
閱讀 2500·2019-08-23 17:19
閱讀 677·2019-08-23 17:18