---
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

## 儲存、取出資料的語法 — 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,再從裡頭的物件觀看想取得的屬性在哪裡。
:::

```
// 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;
}
```