摘要:應(yīng)用緩存的應(yīng)用緩存,或者簡(jiǎn)稱為,是專門為開發(fā)離線應(yīng)用而設(shè)計(jì)的。應(yīng)用緩存還有很多相關(guān)的事件,表示其狀態(tài)的改變。數(shù)據(jù)存儲(chǔ),通常直接叫做,最初是在客戶端用于存儲(chǔ)會(huì)話信息的。也就是使用值來存儲(chǔ)多個(gè)名稱值對(duì)兒。
所謂Web離線應(yīng)用,就是在設(shè)備不能上網(wǎng)的情況下仍然可以運(yùn)行的應(yīng)用。開發(fā)離線Web應(yīng)用需要幾個(gè)步驟:
(1)確保應(yīng)用知道設(shè)備是否能上網(wǎng);
(2)應(yīng)用還必須能訪問一定的資源(圖像、JavaScript、CSS等);
(3)必須有一塊本地空間用于保存數(shù)據(jù),無論能否上網(wǎng)都不妨礙讀寫。
HTML5定義了一個(gè)navigator.onLine屬性,這個(gè)屬性值為true表示設(shè)備能上網(wǎng),值為false表示設(shè)備離線。
多帶帶使用navigator.onLine屬性不能確定網(wǎng)絡(luò)是否連通。即便如此,在請(qǐng)求發(fā)生錯(cuò)誤的情況下,檢測(cè)這個(gè)屬性仍然是管用的。
if(navigator.onLine) { //正常工作 } else { //執(zhí)行離線狀態(tài)時(shí)的任務(wù) }
除了navigator.onLine屬性之外,為了更好地確定網(wǎng)絡(luò)是否可用,HTML5還定義了兩個(gè)事件:onLine和offline。當(dāng)網(wǎng)絡(luò)從離線變?yōu)樵诰€或者從在線變?yōu)殡x線時(shí),分別觸發(fā)這兩個(gè)事件。這兩個(gè)事件在window對(duì)象上觸發(fā)。
//從離線變?yōu)樵诰€ EventUtil.addHandler(window, "online", function() { alert("Online"); }); //從現(xiàn)在變?yōu)殡x線 EventUtil.addHandler(window, "offline", function() { alert("Offline"); });
為了檢測(cè)應(yīng)用是否離線,在網(wǎng)絡(luò)加載后,最好先通過navigator.onLine取得初始的狀態(tài)。然后,就是通過上述兩個(gè)事件來確定網(wǎng)絡(luò)連接狀態(tài)是否變化。當(dāng)上述事件觸發(fā)時(shí),navigator.onLine屬性的值也會(huì)改變。
2、應(yīng)用緩存(1)HTML5的應(yīng)用緩存,或者簡(jiǎn)稱為appache,是專門為開發(fā)離線Web應(yīng)用而設(shè)計(jì)的。Appcache就是從瀏覽器的緩存中分出來的一塊緩存區(qū)。要想在這個(gè)緩存中保存數(shù)據(jù),可使用一個(gè)描述文件(manifest file)列出要下載和緩存的資源。
CACHE MANIFEST #Comment file.js file.css
要將描述文件與頁面關(guān)聯(lián)起來,可以在中的manifest屬性中指定這個(gè)文件的路徑,例如
以上代碼告訴頁面,/offline.manifest中包含著描述文件。
(2)雖然應(yīng)用緩存的意圖是確保離線時(shí)資源可用,但也有相應(yīng)的JavaScript API讓我們知道它都在做什么,這個(gè)API的核心是applicationCache對(duì)象,這個(gè)對(duì)象有一個(gè)status屬性,屬性的值是常量,表示應(yīng)用緩存的如下當(dāng)前狀態(tài)。
0:無緩存,即沒有與頁面相關(guān)的應(yīng)用緩存
1:閑置,即應(yīng)用緩存未得到更新
2:檢查中,即正在下載描述文件并檢查更新
3:下載中,即應(yīng)用緩存正在下載描述文件中的指定資源
4:更新完成,即應(yīng)用緩存已經(jīng)更新了資源,而且所有資源都已下載完畢,可以通過swapCache()來使用了
5:廢棄,即應(yīng)用緩存的描述文件已經(jīng)不存在了,因此頁面無法再訪問緩存。
(3)應(yīng)用緩存還有很多相關(guān)的事件,表示其狀態(tài)的改變。以下是這些事件:
checking:在瀏覽器為應(yīng)用緩存查找更新時(shí)觸發(fā)
error:在檢查更新或下載資源其期間發(fā)生錯(cuò)誤時(shí)觸發(fā)
noupdate:在檢查描述文件發(fā)現(xiàn)文件無變化時(shí)觸發(fā)
downloading:在開始下載應(yīng)用緩存資源時(shí)觸發(fā)
progress:在文件下載應(yīng)用緩存的過程中持續(xù)不斷的觸發(fā)
updateready:在頁面新的應(yīng)用緩存下載完畢且可以通過swapCache()使用時(shí)觸發(fā)
cached:在應(yīng)用緩存完整可用時(shí)觸發(fā)
一般來講,這些時(shí)間會(huì)隨著頁面加載按上述順序依次觸發(fā),不過通過調(diào)用update()方法也可以手工干預(yù),讓應(yīng)用緩存為檢查更新而觸發(fā)上述事件。
applicationCache.update();
update()已經(jīng)一經(jīng)調(diào)用,應(yīng)用緩存就會(huì)去檢查描述文件是否更新(觸發(fā)checking事件),然后就像頁面剛剛加載一樣,繼續(xù)執(zhí)行后續(xù)操作。如果觸發(fā)了cached事件,就說明應(yīng)用緩存已經(jīng)準(zhǔn)備就緒,不會(huì)再發(fā)生其他操作了。如果觸發(fā)了updateready事件,則說明新版本的應(yīng)用緩存已經(jīng)可用,而此時(shí)你需要調(diào)用swapCache()來啟用新應(yīng)用緩存。
Event.addHandler(applicationCache, "updateready", function() { applicationCache.swapCache(); });3、數(shù)據(jù)存儲(chǔ) 3.1 Cookie
HTTP Cookie,通常直接叫做cookie,最初是在客戶端用于存儲(chǔ)會(huì)話信息的。該標(biāo)準(zhǔn)要求服務(wù)器對(duì)任意HTTP請(qǐng)求發(fā)送Set-Cookies HTTP頭作為響應(yīng)的一部分,其中包含會(huì)話信息。例如,這種服務(wù)器響應(yīng)頭可能如下:
HTTP/1.1 200 OK Content-type: text/html Set-Cookie: name=value Other-header: other-header-value
這個(gè)HTTP響應(yīng)設(shè)置以name為名稱,以value為值得一個(gè)cookie,名稱和值在傳送時(shí)都必須是URL編碼的。瀏覽器會(huì)存儲(chǔ)這樣的會(huì)話信息,并在這之后,通過為每個(gè)請(qǐng)求添加Cookie HTTP頭將信息發(fā)送回服務(wù)器。
GET /index.html HTTP/1.1 Cookie: name=value Other-header: other-header-value
發(fā)送回服務(wù)器的額外信息可以用于唯一驗(yàn)證客戶來自于發(fā)送的哪個(gè)請(qǐng)求。
1、限制(綁定在特定域名下;數(shù)量限制;尺寸限制)
(1)cookie在性質(zhì)上是綁定在特定的域名下的。當(dāng)設(shè)定了一個(gè)cookie后,再給創(chuàng)建它的域名發(fā)送請(qǐng)求時(shí),都會(huì)包含這個(gè)cookie。這個(gè)限制確保里存儲(chǔ)在cookie中的信息只能讓批準(zhǔn)的接受者訪問,而無法被其他域訪問。
(2)每個(gè)域的cookie總數(shù)總是有限的,當(dāng)超過單個(gè)域名限制之后還要再設(shè)置cookie,瀏覽器就會(huì)清除以前設(shè)置的cookie。IE和Opera會(huì)刪除最近最少使用過的cookie,騰出空間給新設(shè)置的cookie。Firefox看上去好像是隨機(jī)決定要清除哪個(gè)cookie,所以考慮cookie限制非常重要,以免出現(xiàn)不可預(yù)期的后果。
(3)瀏覽器中對(duì)于cookie的尺寸也有限制。尺寸限制影響到一個(gè)域下所有的cookie,而并非每個(gè)cookie多帶帶限制。如果你嘗試創(chuàng)建超過最大尺寸限制的cookie,那么該cookie會(huì)被悄無聲息地丟掉。
2、cookie的構(gòu)成
cookie由瀏覽器保存的一下幾塊信息構(gòu)成。(名稱、值、域、路徑、失效時(shí)間、安全標(biāo)志)
名稱:一個(gè)唯一確定cookie的名稱。cookie名稱是不區(qū)分大小寫的,但是實(shí)踐中最好將cookie名稱看作是區(qū)分大小寫的。cookie的名稱必須是經(jīng)過URL編碼的。
值:存儲(chǔ)在cookie中的字符串值。值必須被URL編碼。
域:cookie對(duì)于哪個(gè)域是有效的。所有向該域發(fā)送的請(qǐng)求都會(huì)包含這個(gè)cookie信息。這個(gè)值可以包含子域(subdomain,如www.wrox.com),也可以不包含它(如.wrox.com,則對(duì)于wrox.com的所有子域都有效)。如果沒有明確設(shè)定,那么這個(gè)域會(huì)被認(rèn)作來自設(shè)置cookie的那個(gè)域。
路徑:對(duì)于指定域中的那個(gè)路徑,應(yīng)該向服務(wù)器發(fā)送cookie。例如,你可以指定cookie只有從http://www.wrox.com/books/ 中才能訪問,那么http://www.wrox.com 的頁面就不會(huì)發(fā)送cookie信息,即使請(qǐng)求都是來自于同一個(gè)域的。
失效時(shí)間:表示cookie何時(shí)應(yīng)該被刪除的時(shí)間戳(也就是,何時(shí)應(yīng)該停止向服務(wù)器發(fā)送這個(gè)cookie)。默認(rèn)情況下,瀏覽器會(huì)話結(jié)束時(shí)即將所有cookie刪除;不過也可以自己設(shè)置刪除時(shí)間。這個(gè)值是個(gè)GMT格式的日期,用于指定應(yīng)該刪除cookie的準(zhǔn)確時(shí)間。cookie可在瀏覽器關(guān)閉后依然保存在用戶的機(jī)器上。如果你設(shè)置的失效日期是個(gè)以前的時(shí)間,則cookie會(huì)被立即刪除。
安全標(biāo)志:指定后,cookie只有在使用SSL連接的時(shí)候才發(fā)送到服務(wù)器。例如,cookie信息只能發(fā)送給https://www.wrox.com,而 http://www.wrox.com 的請(qǐng)求則不能發(fā)送。
每一段信息都作為Set-Cookie頭的一部分,使用分號(hào)加空格分隔每一段,如下例所示:
HTTP/1.1 200 OK Content-type: text/html Set-Cookie: name=value; expires=Mon, 22-Jan-07 07:10:24 GMT; domain=.wrox.com Other-header: other-header-value
secure標(biāo)志是cookie中唯一一個(gè)非名值對(duì)兒的部分,直接包含一個(gè)secure單詞。
HTTP/1.1 200 OK Content-type: text/html Set-Cookie: name=value; domain=.wrox.com; path=/; secure Other-header: other-header-value
這里創(chuàng)建了一個(gè)對(duì)于所有wrox.com的子域和域名下(由path參數(shù)指定的)所有頁面都是有效的cookie。因?yàn)樵O(shè)置了secure標(biāo)志,這個(gè)cookie只能通過SSL連接才能傳輸。
尤其要注意,域、路徑、失效時(shí)間和secure標(biāo)志都是服務(wù)器給瀏覽器的指示,以指定何時(shí)應(yīng)該發(fā)送cookie。這些參數(shù)并不會(huì)作為發(fā)送到服務(wù)器的cookie信息的一部分,只有名值對(duì)兒才會(huì)被發(fā)送。
3、JavaScript中的cookie
JavaScript中處理cookie有些復(fù)雜,因?yàn)锽OM的document.cookie屬性比較獨(dú)特,它會(huì)因?yàn)槭褂盟牟煌憩F(xiàn)出不同的行為。
當(dāng)用來獲取屬性值時(shí),document.cookie返回當(dāng)前頁面可用的(根據(jù)cookie的域、路徑、失效時(shí)間和安全設(shè)置)所有cookie的字符串,一系列由分號(hào)隔開的名值對(duì)兒。
當(dāng)用于設(shè)置值的時(shí)候,document.cookie屬性可以設(shè)置為一個(gè)新的cookie字符串。這個(gè)cookie字符串會(huì)被解釋并添加到現(xiàn)有的cookie集合中。設(shè)置document.cookie并不會(huì)覆蓋cookie,除非設(shè)置cookie的名稱已經(jīng)存在。設(shè)置cookie的格式如下,和Set-Cookie頭中使用的格式一樣。
name=value; expires=expiration_time; path=domain_name; secure
這些參數(shù)中,只有cookie的名字和值是必需的。如:最好每次設(shè)置cookie時(shí)都像下面這樣使用encodeURI-Component();
document.cookie = encodeURIComponent("name") + "=" + encodeURIComponent("Nicholas");
要給被創(chuàng)建的cookie指定額外的信息,只要將參數(shù)追加到該字符串,和Set-Cookie頭中的格式一樣,如下所示:
document.cookie = encodeURIComponent("name") + "=" + encodeURIComponent("Nicholas") + "; domain=.wrox.com; path=/";
由于JavaScript中讀寫cookie不是非常直觀,常常需要寫一些函數(shù)來簡(jiǎn)化cookie功能。基本的cookie操作有3種:讀取、寫入和刪除。
所有名字和值都是經(jīng)過URL編碼的,所有必須使用decodeURIComponent()來解碼
var CookieUtil = { get: function(name){ //查找cookie名加上等于號(hào)的位置。如果找到了,那么使用indexOf()查找該位置之后的第一個(gè)分號(hào)(表示了該cookie的結(jié)束位置)。如果沒有找到分號(hào),則表示該cookie是字符串中的最后一個(gè),則余下的字符串都是cookie的值。該值使用decodeURIComponent()進(jìn)行解碼并最后返回。如果沒有發(fā)現(xiàn)cookie,則返回null。 var cookieName = encodeURIComponent(name) + "=", cookieStart = document.cookie.indexOf(cookieName), cookieValue = null; if(cookieStart > -1){ var cookieEnd = document.cookie.indexOf(";",cookieStart); if(cookieEnd == -1){ cookieEnd = document.cookie.length; } cookieValue = decodeURIComponent(document.cookie.substring(cookieStart+cookieName.length,cookieEnd)); } return cookieValue; }, set: function(name, value, expires, path, domain, secure) { var cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(value); if(expires instanceof Date) { cookieText += "; expires=" + expires.toGMTString(); } if(path) { cookieText += "; path=" + path; } if(domain) { cookieText += "; domain=" + domain; } if(secure) { cookieText += "; secure"; } document.cookie = cookieText; }, //沒有刪除已有cookie的直接方法。所以,需要使用相同的路徑、域和安全選項(xiàng)再次設(shè)置cookie,并將失效時(shí)間設(shè)置為過去的時(shí)間。 unset: function (name, path, domain, secure) { this.set(name, "", new Date(0), path, domain, secure); } };
然后就可以像下面這樣使用上述方法
//設(shè)置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");
4、子cookie
為了繞開瀏覽器的單域名下的cookie數(shù)限制,一些開發(fā)人員使用了一種稱為子cookie(subcookie)的概念。子cookie是存放在的那個(gè)cookie中的更小段的數(shù)據(jù)。也就是使用cookie值來存儲(chǔ)多個(gè)名稱值對(duì)兒。子cookie最常見的格式如下
name=name1=value1&name2=value2&name3=value3&name4=value4&name5=value5
子cookie一般也以查詢字符串否認(rèn)格式進(jìn)行格式化。然后這些值可以使用單個(gè)cookie進(jìn)行存儲(chǔ)和訪問,而非對(duì)每個(gè)名稱-值對(duì)兒使用不同的cookie存儲(chǔ)。最后網(wǎng)站或者微博應(yīng)用程序可以無需達(dá)到單域名cookie上限也可以存儲(chǔ)更加結(jié)構(gòu)化的數(shù)據(jù)。
為了更好地操作子cookie,必須建立一系列新的方法。子cookie的解析序列和序列化會(huì)因子cookie的期望用途而略有不同并更加復(fù)雜些。
獲取子cookie的方法有兩個(gè):get()和getAll()。其中g(shù)et()獲取單個(gè)子cookie的值,getAll()獲取所有子cookie并將它們放入一個(gè)對(duì)象中返回,對(duì)象的屬性為子cookie的名稱,對(duì)應(yīng)值為子cookie對(duì)應(yīng)的值。get()方法接收兩個(gè)參數(shù):cookie的名字和子cookie的名字。它其實(shí)就是調(diào)用getAll()獲取所有的子cookie,然后只返回所需的那一個(gè)(如果cookie不存在則返回null)。
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; }
要設(shè)置子cookie,也有兩種方法:set()和setAll().為了在同一個(gè)cookie中存儲(chǔ)多個(gè)子cookie,路徑、域和secure標(biāo)志必須一致;針對(duì)整個(gè)cookie的失效日期則可以在任何一個(gè)多帶帶的子cookie寫入的時(shí)候同時(shí)設(shè)置。在這個(gè)set()方法中,第一步是獲取指定cookie名稱對(duì)應(yīng)的所有子cookie。邏輯或操作符"||"用于當(dāng)getAll()返回null時(shí)將subcookies設(shè)置為一個(gè)新對(duì)象。然后,在subcookies對(duì)象上設(shè)置好子cookie值并傳給setAll()。
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 (subcookieParts.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可以通過將失效時(shí)間設(shè)置為過去的時(shí)間的方法來刪除,但是子cookie不能這樣做。為了刪除一個(gè)子cookie,首先必須獲取包含在某個(gè)cookie中的所有子cookie,然后再將余下的子cookie的值保存為cookie的值。
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); }
整個(gè)SubCookieUtil部分代碼如下:
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; }, 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 (subcookieParts.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; }, 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); } };
可以像下面這樣使用上述方法:
//取得全部子cookie var data = SubCookieUtil.getAll("data"); alert(data.name); //"Nicholas" alert(data.book); //"Professional JavaScript" //逐個(gè)獲取子cookie alert(SubCookieUtil.get("data","name")); //"Nicholas" alert(SubCookieUtil.get("data","book")); //"Professional JavaScript" //設(shè)置兩個(gè)cookie SubCookieUtil.set("data", "name", "Nicholas"); SubCookieUtil.set("data", "book", "Professional JavaScript"); //設(shè)置全部子cookie和失效日期 SubCookieUtil.setAll("data",{name:"Nicholas", book:"Professional JavaScript"},new Date("January 1, 2010")); //修改名字的值,并修改cookie的失效日期 SubCookieUtil.set("data", "name", "Michael", new Date("February 1,2010"));
5、關(guān)于cookie的思考
還有一類cookie被稱為“HTTP專有cookie”。HTTP專有cookie可以從瀏覽器或者服務(wù)器設(shè)置,但是只能從服務(wù)器端讀取。由于所有的cookie都會(huì)由瀏覽器作為請(qǐng)求頭發(fā)送,所以在cookie中存儲(chǔ)大量信息會(huì)影響到特定域請(qǐng)求性能。cookie信息越大,完成對(duì)服務(wù)器請(qǐng)求的時(shí)間也就越長(zhǎng)。盡管瀏覽器對(duì)cookie進(jìn)行了大小限制,不過最好還是盡可能在cookie中少儲(chǔ)存信息,以避免影響性能。
cookie的性質(zhì)和它的局限使得并不能作為存儲(chǔ)大量信息的理想手段。
一定不要在cookie中存儲(chǔ)重要和敏感的數(shù)據(jù)。
微軟通過一個(gè)自定義行為引入了持久化用戶數(shù)據(jù)的概念。要使用持久化用戶數(shù)據(jù),首先必須如下所示,使用CSS在某個(gè)元素上指定userData行為:
一旦該元素使用了userDate行為,那么就可以(1)使用setAttribute()方法在上面保存數(shù)據(jù)了。為了將數(shù)據(jù)提交到瀏覽器緩存中,還必須(2)調(diào)用save()方法并告訴它要保存到的數(shù)據(jù)空間的名字。數(shù)據(jù)空間名字可以完全任意,僅用于區(qū)分不同數(shù)據(jù)集。(3)下一次頁面載入之后,可以使用load()方法指定同樣的數(shù)據(jù)空間名稱來獲取數(shù)據(jù)。
var dataStore = document.getElementById("dataStore"); dataStore.setAttribute("name", "Nicholas"); dataStore.setAttribute("book","Professional JavaScript"); datastore.save("BookInfo"); //指定了數(shù)據(jù)空間的名稱為BookInfo dataStore.load("BookInfo"); alert(dataStore.getAttribute("name")); //"Nicholas" alert(dataStore.getAttribute("book")); //"Professional JavaScript"
對(duì)load()的調(diào)用獲取了BookInfo數(shù)據(jù)空間中的所有信息,并且使數(shù)據(jù)可以通過元素訪問;只有到載入確切完成之后數(shù)據(jù)方能使用。如果getAttribute()調(diào)用了不存在的名稱或者是尚未載入的名稱,則返回null。
通過removeAttribute()方法明確指定要?jiǎng)h除某元素?cái)?shù)據(jù),只要指定屬性名稱。刪除之后,必須像下面這樣再次調(diào)用save()來提交更改。
dataStore.removeAttribute("name"); dataStore.removeAttribute("book"); dataStore.save("BookInfo");
和cookie一樣,IE用戶數(shù)據(jù)并非安全的,所以不能存放敏感信息。
3.3 Web存儲(chǔ)機(jī)制 3.4 IndexedDB文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/109296.html
摘要:哪吒社區(qū)技能樹打卡打卡貼函數(shù)式接口簡(jiǎn)介領(lǐng)域優(yōu)質(zhì)創(chuàng)作者哪吒公眾號(hào)作者架構(gòu)師奮斗者掃描主頁左側(cè)二維碼,加入群聊,一起學(xué)習(xí)一起進(jìn)步歡迎點(diǎn)贊收藏留言前情提要無意間聽到領(lǐng)導(dǎo)們的談話,現(xiàn)在公司的現(xiàn)狀是碼農(nóng)太多,但能獨(dú)立帶隊(duì)的人太少,簡(jiǎn)而言之,不缺干 ? 哪吒社區(qū)Java技能樹打卡?【打卡貼 day2...
摘要:設(shè)定的值的時(shí)候,即已自動(dòng)暗示類型。第五章循環(huán)自我重復(fù)的風(fēng)險(xiǎn)數(shù)組用于在單一場(chǎng)所存儲(chǔ)多段數(shù)據(jù)數(shù)組的頁碼稱為鍵,索引只是一種形式特殊的鍵,它是數(shù)值鍵存儲(chǔ)在數(shù)組里的數(shù)據(jù)不一定為相同類型并不要求二維數(shù)組具有相同的行數(shù),但是最好保持一致。 ** 簡(jiǎn)介 **書名:《Head First JavaScript》中文譯名:《深入淺出JavaScript》著:Michael Morrison編譯:O’R...
摘要:在近期看到了函數(shù)式編程這本書預(yù)售的時(shí)候就定了下來。主要目的是個(gè)人目前還是不理解什么是函數(shù)式編程。且和現(xiàn)在在學(xué)習(xí)函數(shù)式編程有莫大的關(guān)系。加速大概了解了函數(shù)式編程之后??偨Y(jié)看完了第一章也是可以小結(jié)一下的函數(shù)式編程。 本文章記錄本人在學(xué)習(xí) 函數(shù)式 中理解到的一些東西,加深記憶和并且整理記錄下來,方便之后的復(fù)習(xí)。 在近期看到了《JavaScript函數(shù)式編程》這本書預(yù)售的時(shí)候就定了下...
摘要:貢獻(xiàn)者飛龍版本最近總是有人問我,把這些資料看完一遍要用多長(zhǎng)時(shí)間,如果你一本書一本書看的話,的確要用很長(zhǎng)時(shí)間。為了方便大家,我就把每本書的章節(jié)拆開,再按照知識(shí)點(diǎn)合并,手動(dòng)整理了這個(gè)知識(shí)樹。 Special Sponsors showImg(https://segmentfault.com/img/remote/1460000018907426?w=1760&h=200); 貢獻(xiàn)者:飛龍版...
摘要:性能訪問字面量和局部變量的速度是最快的,訪問數(shù)組和對(duì)象成員相對(duì)較慢變量標(biāo)識(shí)符解析過程搜索執(zhí)行環(huán)境的作用域鏈,查找同名標(biāo)識(shí)符。建議將全局變量存儲(chǔ)到局部變量,加快讀寫速度。優(yōu)化建議將常用的跨作用域變量存儲(chǔ)到局部變量,然后直接訪問局部變量。 缺陷 這本書是2010年出版的,這本書談性能是有時(shí)效性的,現(xiàn)在馬上就2018年了,這幾年前端發(fā)展的速度是飛快的,書里面還有一些內(nèi)容考慮IE6、7、8的東...
閱讀 687·2021-10-09 09:41
閱讀 673·2019-08-30 15:53
閱讀 1100·2019-08-30 15:53
閱讀 1235·2019-08-30 11:01
閱讀 1596·2019-08-29 17:31
閱讀 1018·2019-08-29 14:05
閱讀 1747·2019-08-29 12:49
閱讀 434·2019-08-28 18:17