--- title: 'JS 入門 - localStorage 瀏覽器資料儲存' tags: JS, Javascript, localStorage description: 2021/01/26 --- JS 入門 -- localStorage 瀏覽器資料儲存 === ## 資料如何儲存在瀏覽器? 1. 透過 HTML 中的網頁儲存物件,可以將網頁中的資料儲存在使用者的瀏覽器當中。 2. 可以在(client)客戶端儲存資料。使用上的好處在於大部分瀏覽器都有支援、可以儲存資料的容量大多有 5MB 以上、且資料儲存和提取相對簡單方便。 3. 網頁儲存物件分為兩種,雖然都能將資料暫存在當下頁面的 Storage 物件裡,但是資料保存的時間不同。 * **localStorage**:可以跨瀏覽器分頁做使用、使用者關掉分頁或瀏覽器再打開資料仍不會消失,且資料無期效限制,資料將永久被保留。 * **sessionStorage**:生命週期較短,當使用者關掉瀏覽器或分頁時,sessionStorage 中的資料將被清空。 4. localStorage 儲存位置 : 在 DevTools Application 中查看 localStorage ![](https://i.imgur.com/4d7ksbG.png) ## 儲存、取出資料的語法 — setItem、getItem `key 屬性名 、 value 相對應的值` ### 存入資料 setItem ( key, value ) ```typescript var str = 'TOM'; localStorage.setItem ('myName', str); sessionStorage.setItem ('myName', str); ``` ### 取出資料 getItem ( key ) ```typescript localStorage.getItem ('myName'); sessionStorage.getItem ('myName'); ``` ### 移除資料 removeItem ( key ) ```typescript localStorage.removeItem ('myName'); sessionStorage.removeItem ('myName'); ``` :bulb: **範例 :** 如何把使用者鍵入的資料用 localStorge 存起來 ```typescript <h3>請輸入您的名字</h3> <input type="text" class="textClass"> <button type="button" class="btnClass">名字存入 localStorage</button> <button type="button" class="btnCall">從 localStorage 呼叫名字</button> <p class="showName"></p> ``` ```typescript var btn = document.querySelector('.btnClass'); var call = document.querySelector('.btnCall'); btn.addEventListener('click', saveName, false); // 把名字存進 localStorage call.addEventListener('click', getName, false); // 從 localStorage 把名字取出 function saveName () { var str = document.querySelector('.textClass').value; console.log(str); localStorage.setItem('myName', str); }; function getName () { var str = localStorage.getItem('myName'); console.log(str); document.querySelector('.showName').textContent = str; }; ``` <style> .red { color: red; } </style> ## 透過 JSON.parse、JSON.stringify 來編譯資料 <span class="red">localStorage 只能儲存字串資料。</span> ### 把陣列轉換成字串:JSON.stringify ( ) ```typescript= var country = [ { farmer: 'Tom' } ]; var countryStr = JSON.stringify(country); // 變字串 console.log(countryStr); // [{"farmer":"Tom"}] localStorage.setItem('countryItem', countryStr); ``` ### 把字串轉換成陣列 : JSON.parse ( ) ```typescript=8 var getData = localStorage.getItem('countryItem'); console.log(typeof(getData)); // string var getDataAry = JSON.parse(getData); console.log(typeof(getDataAry)); // object console.log(country[0].farmer); // Tom ``` ### :bulb: 範例 : todo List ``` <div class="wrap d-flex"> <img class="img" src="https://upload.cc/i1/2021/01/19/14pDL2.jpg" alt="農場備忘錄圖片"> <div class="addList"> <input type="text" class="text"> <input type="button" class="send" value="加入代辦"> <ul class="list"></ul> </div> </div> ``` 1. 每次在新增或刪除清單時,要再呼叫updataList ( ) ; 這個方法讓畫面更新並重新載入頁面(刷新資料)。 2. 除了會更新data陣列外,也會更新儲存在localStorage中的資料,以確保分頁或瀏覽器被關閉時,資料不會遺失。 3. (不建議的做法) .querySelector 只能抓第一筆資料,測試一下只有第一筆有反應。 4. (建議作法) 指定 ul 監聽各種事項,再查詢 e.target,如果是點到 li 再做事情。 5. target 是搭配監聽,當下監聽到的e裡的target而做反應,所以不能用在一般的讀取上。 ```typescript var list = document.querySelector('.list'); var sendData = document.querySelector('.send'); var data = JSON.parse(localStorage.getItem('listData')) || []; // 若 localStorage 無資料,就預設為空陣列 [] // 監聽與更新 sendData.addEventListener('click', addData); list.addEventListener('click', toggleDone); updateList(data); // 加入列表,並同步更新網頁與 localStorage function addData (e) { e.preventDefault(); var txt = document.querySelector('.text').value; var todo = { content: txt }; data.push(todo); updateList(data); localStorage.setItem('listData', JSON.stringify(data)); } // 更新網頁內容 function updateList (items) { var len = items.length; var str = ''; for (let i = 0; i < len; i++) { var text = `<li> <a href="#" data-index="${i}"> 刪除 </a> <span> ${ items[i].content } </span> </li>`; str += text; } list.innerHTML = str; }; // 刪除代辦事項 function toggleDone (e) { e.preventDefault(); if(e.target.nodeName !== "A"){return}; var index = e.target.dataset.index; data.splice(index, 1); localStorage.setItem('listData', JSON.stringify(data)); updateList (data); // 刪除 array 資料後(編號會更動),要再重新渲染一次 }; ``` ## :memo: 筆記 :::info **target 的使用時機 :** 「當你要抓下當下點擊元素的詳細資訊時用」。 實際上來說都會看自己想要取得監聽資訊裡的哪個內容而訂,所以有時會從 e 取得、或者從 e.target,再從裡頭的物件觀看想取得的屬性在哪裡。 ::: ![](https://i.imgur.com/5bSwHb0.png) ``` // CSS img { display: block; } a { text-decoration: none; font-weight: 700; color:#a47c64; } a:hover{ color: #FFCC66; } .d-flex{ display: flex; justify-content: space-between; } .wrap{ max-width: 500px; margin: 0 auto; padding: 50px 0; } .addList { padding-top: 20px; } .text { padding: 10px 8px; } .send { padding: 10px 8px; background:#f9eed3; border:1px solid #a47c64; color:#a47c64; } .list{ padding: 20px 0; margin-left: 20px; font-size: 20px; } .list li { margin: 5px; } input[type=text] , input[type=button] { border:2px solid #a47c64; border-radius: 5%; font-weight: 600; } input[type=button]{ cursor: pointer; } ```