HTML5 – 本地存儲
HTML5 Web Storage API 讓在本地存儲數(shù)據(jù)成為了可能,而且可以存儲 5M 的數(shù)據(jù),這 5M 的空間可供一個(gè)域任意使用。注意是一個(gè)域,這也就是說所保存的數(shù)據(jù)是不可跨域訪問的。
我一向喜歡在實(shí)踐中學(xué)習(xí)新的知識,今天也不例外,我利用 loalStorage 做了一個(gè)便簽小應(yīng)用,數(shù)據(jù)存放在瀏覽器中。
怎么樣,還不錯(cuò)吧?下面就用這個(gè)例子的開發(fā)流程來介紹 localStorage 吧!
起步
在這里,我就不在粘貼 HTML 和 CSS 代碼了,如果你想在本地運(yùn)行這個(gè)例子,我將在文章末尾給出源碼下載地址。
首先,我想講講該怎么創(chuàng)建這么一個(gè)便簽,它的具體過程應(yīng)該像下面這樣。
- 獲取用戶輸入的內(nèi)容
- 獲取便簽的等級,這個(gè)是在 <select> 中選擇的。
- 將內(nèi)容和等級保存在一個(gè)對象中,利用 JSON 轉(zhuǎn)換為字符串。
- 生成一個(gè) key, 用于保存數(shù)據(jù),為了查找方便,創(chuàng)建一個(gè)數(shù)組,單獨(dú)來存儲 key, 當(dāng)然這個(gè)數(shù)組也利用 JSON 轉(zhuǎn)換成字符串。
- 使用 localStorage 的 setItem() 方法保存便簽對象和 key數(shù)組字符串。
- 將標(biāo)簽添加到 DOM 結(jié)構(gòu)。
按照上述流程,可以編寫下面的代碼
- function createNote() {
- var noteElement = document.getElementById("note");
- var noteValue = noteElement.value;
- noteElement.value = "";
- var levelObj = document.getElementById("note-level");
- var index = levelObj.selectedIndex;
- var level = levelObj[index].value;
- var noteObj = {
- "value": noteValue,
- "level": level
- }
- var date = new Date();
- var key = "note_" + date.getTime();
- localStorage.setItem(key, JSON.stringify(noteObj));
- var notesArray = getNotesArray();
- notesArray.push(key);
- localStorage.setItem("notesArray", JSON.stringify(notesArray));
- addNoteToDOM(key, noteObj);
- }
值得注意的是,localStorage 只能保存字符串的值,所以我們在這里才不得不使用 JSON 將其轉(zhuǎn)換成字符串。你可以使用下屬代碼存儲一個(gè)整數(shù)或者浮點(diǎn)數(shù)。
- localStorage.setItem("my_num",10);
這行代碼確實(shí)可以運(yùn)行,那是因?yàn)?JS 自動(dòng)將其轉(zhuǎn)換成了字符串,所以如果你想取出一個(gè)整數(shù),你不得不進(jìn)行轉(zhuǎn)換,就像下面這樣。
- var num = parseInt(localStorage.getItem("my_num"));
上面的代碼中,使用了兩個(gè)自定義的函數(shù),那就是 getNotesArray() 和 addNoteToDOM(),根據(jù)名字可以很容易判斷出它們的功能。不過讓人費(fèi)解的是,我們?yōu)槭裁匆獙iT使用一個(gè)數(shù)組去保存 key 呢?
有一點(diǎn)你需要知道,在實(shí)際的網(wǎng)站中,你不可能只存儲便簽吧?你還需要存儲很多其它的數(shù)據(jù),如果保存了大量的其它數(shù)據(jù),那么尋找便簽就是一項(xiàng)十分耗時(shí)的任務(wù)了。我為什么要尋找便簽?
如果你的用戶關(guān)掉了瀏覽器,然后又重新打開了這個(gè)網(wǎng)站怎么辦呢?這個(gè)時(shí)候我們就不得不去尋找便簽了。好了,下面來看看 getNotesArray() 函數(shù)吧~
- function getNotesArray() {
- var notesArray = localStorage.getItem("notesArray");
- if (!notesArray) {
- notesArray = [];
- localStorage.setItem("notesArray", JSON.stringify(notesArray));
- } else {
- notesArray = JSON.parse(notesArray);
- }
- return notesArray;
- }
利用 localStorage.getItem() 去獲取這個(gè)數(shù)組,如果這個(gè)數(shù)組不存在就創(chuàng)建一個(gè),然后將其轉(zhuǎn)換成字符串保存起來,如果數(shù)組已經(jīng)存在,那就將其從字符串轉(zhuǎn)成數(shù)組。總之,要返回一個(gè)數(shù)組,供我們使用。
好了,大概已經(jīng)知道了,下面就是 addNoteToDOM() 函數(shù)了,這個(gè)函數(shù)就更簡單啦,下面來看看。
- function addNoteToDOM(key, noteObj) {
- var notes = document.getElementById("note-list");
- var note = document.createElement("li");
- note.setAttribute("id", key);
- note.onclick = deleteNote;
- var value = noteObj.value;
- note.innerHTML = value;
- var level = noteObj.level;
- note.setAttribute("class", level);
- notes.appendChild(note);
- }
首先,需要解釋一點(diǎn),#note-list 是一個(gè) <ul> 元素,而且我們的便簽也都是由其子元素 <li> 組成的。接下來就簡單了,我們將值賦給 <li>, 然后根據(jù)標(biāo)簽的等級為其添加不同的背景顏色,這里是通過為其設(shè)置 class 來達(dá)到這一目的。
值得注意的是,這里我們將 key 作為參數(shù)傳遞進(jìn)來了,而且利用 key 的值為 <li> 設(shè)置了 id 屬性,這是為了達(dá)到刪除的目的,畢竟我們不能只創(chuàng)建標(biāo)簽而不知道如果刪除吧,所以在這里還為 <li> 設(shè)置了點(diǎn)擊事件。
- function deleteNote(e) {
- var key = e.target.id;
- localStorage.removeItem(key);
- var notesArray = getNotesArray();
- for (var i = 0; i < notesArray.length; i++) {
- if (key === notesArray[i]) {
- notesArray.splice(i, 1);
- }
- }
- localStorage.setItem("notesArray", JSON.stringify(notesArray));
- deleteNoteFromDOM(key);
- }
當(dāng) <li> 元素被點(diǎn)擊,就會(huì)傳進(jìn)來一個(gè) event 對象,通過 target 就可以獲得觸發(fā)事件的對象,我們獲取到這個(gè)對象的 id, 將其從 DOM 刪除。
不過這個(gè)不是重點(diǎn),刪除標(biāo)簽,意味著,我們還需要將其從本地存儲中將其值刪除,而且要把它從 key 數(shù)組中除名,我們用 removeItem 和 splice() 來大到了這一目的。
拓展
上面,我們已經(jīng)把 localStorage 的使用講解完畢了,而且上面的代碼包含了便簽應(yīng)用的核心代碼。值得一提的是,還有一個(gè) sessionStorage ,它的使用和 localStorage 完全相同,唯一不同的是,一旦瀏覽器窗口關(guān)閉,保存的數(shù)據(jù)將會(huì)被全部刪除。
當(dāng)然,這是 HTML5 中的屬性,所以我們在使用的時(shí)候需要進(jìn)行檢測,可以使用下面的代碼檢測瀏覽器是否支持 localStorage。
- if (window["localStorage"]) {
- // your logic code
- }