Day29 | localStorage 瀏覽器資料儲存

❒ 什麼是 localStorage ?

  • 瀏覽器裡面的資料,可從 chrome 開發者工具 / Application 中的 Storage 查看。
    Chrome 開發者工具 Application 中的 Storage 截圖

❒ setItem、getItem 基本操作

setItem : 可把值帶入 Local Storage 的 KeyValue 內。

getItem : 可把 Local Storage 內的 KeyValue 值取出來。

➊ Chrome 開發者工具查看 localStorage

開發者工具localStorage位置

➋ 如何在 Local Storage 中帶入 Key 與 Value 的值 ?

語法: localStorage.setItem('key值' , 'value值');

  • 使用 setItem 可以分別把第一個值帶入 Key 裡,第二個值會帶入 Value 中。

  • 下方範例,另外寫變數帶入 localStorage.setItem('值1' , 值2 ); 內。

    1
    2
    const str ='tom';
    localStorage.setItem('myName' , str);

    Local Storage 中Key與Value 值

➌ 如何在 Local Storage 中撈出 value 值 ?

語法: localStorage.getItem('key值');

  • 當中的值為 Local Storage 中的 Key ,填入後可撈出 Value

    1
    2
    3
    4
    5
    6
    const str ='tom';
    //使用setItem把 key & value 值帶入
    localStorage.setItem('myName' , str);

    //這邊於前方加入 console.log 包裹,方便查看撈出的值是否為 tom
    console.log(localStorage.getItem('myName'));

    開發者工具截圖

範例 1

  1. 輸入文字到 .texClass 文字框內
  2. 點擊按鈕會把文字帶入到開發者工具 Local Storage 的 value 內。
  3. 按下點擊呼叫名字的按鈕,會出現上方輸入文字框內的文字。
1
2
3
4
<h2>請輸入你的名字</h2>
<input type="text" class="texClass">
<input type="button" class="btnClass" value="點擊">
<input type="button" class="btnCall" value="點擊呼叫名字">
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const texClass = document.querySelector('.texClass');
const btnClass = document.querySelector('.btnClass');
const btnCall = document.querySelector('.btnCall');

//監聽 click
btnClass.addEventListener('click', showName);

function showName(e) {
const nameVal = texClass.value;
localStorage.setItem('myName', nameVal); //key為myName, value為input輸入的文字
}
//監聽 btnCall
btnCall.addEventListener('click', function (e) {
//上方帶入key為myName這個值,這邊使用key為myNamekey的值撈出它的 value
const texname = localStorage.getItem('myName');
alert('我的名字為' + texname);
})

❒ 透過 JSON.parse、JSON.stringify 來編譯資料

➊ localstorage 只會保存 string 資料,所以需學下方兩點

  1. 將 array 轉為 string → JSON.stringify()
    • localStorage.setItem("值1",JSON.stringify(值2));
    • Local Storage 只能存放字串,所以要利用 JSON.stringify 把陣列轉成字串。
    • 當我們要存資料到 Local Storage 時,不論是 JSON 或 object 都須轉為 string 。
  2. 將 string 轉為 array → JSON.parse()
    • JSON.parse(localStorage.getItem("值"));
    • Local Storage 取出的字串,使用 JSON.parse 把字串解析成陣列可讀取的資料。
    • 從資料庫或是 Local Storage 撈出資料基本上都會是 string 格式,需要把它變 JSON 格式就須搭配 JSON.parse(),這樣我們才可透過 array 格式取出資料內的值。
  3. 可參考 To do list 範例 Codepen

➋ 將 array 轉為 string & string 轉為 array

1
2
3
4
5
// array 轉為 string 
localStorage.setItem("key名稱",JSON.stringify(value值));

// string 轉為 array
JSON.parse(localStorage.getItem("key名稱"));

範例 1. 為什麼要把 array 轉為 string

直接把 array 帶入 Local Storage 發現陣列資料以字串方式呈現

  • 使用 Local Storage 會自動把 array 轉為 string 的內容,如果想把變數 farm 的陣列顯示在 value 上,這時就需要把陣列字串化 ( array → string ) 才能顯示在 value 上。

    1
    2
    3
    4
    5
    6
    7
    8
    const farm = [
    {
    farmer:'傑森'
    }
    ];

    // 沒把陣列轉字串,value 只出現 [object Object]
    localStorage.setItem('farmItem',farm);

    開發者工具截圖

試著把陣列資料撈出並查詢是哪種型別

  • 最後使用撈出 farm 陣列中第一筆資料,發現 undefined ,這時可以使用 console.log(typeof(getData)); 查詢 getData 的型別,發現是 string 而非 array。

    1
    2
    3
    4
    5
    6
    7
    8
    const farm = [
    {
    farmer:'傑森'
    }
    ];
    localStorage.setItem('farmItem', farm); //把值帶入 Local Storage的Key與Value 內。
    const getData = localStorage.getItem('farmItem'); //取出key名為farmItem的value值
    console.log(getData[0].farmer); //撈出陣列中第一筆農夫資料,發現undefined

    開發者工具截圖

把陣列字串化,即可把 key 與 value 值帶入 Local Storage 內

Local Storage 只能存放字串,所以要利用 JSON.stringify 把陣列轉成字串。

  • farm 的陣列資料使用 JSON.stringify 編譯過後,開發者工具中的 Console 從 undefined[{"farmer":"傑森"}] ,這時就可使用 setItem 帶入 key 與 value 的值。從開發者工具的 Application 觀看 value 值也從 [object ,Object][{"farmer":"傑森"}] ,陣列字串化成功 !

    1
    2
    3
    4
    5
    6
    7
    const farm = [
    {farmer:'傑森'}
    ];

    const farmString = JSON.stringify(farm); //把array字串化
    //console.log(farmString);
    localStorage.setItem('farmItem',farmString);

    截圖
    截圖

撈出 Local Storage 的 value 值

使用 JSON.parse 把字串解析成陣列可讀取的資料。

  • 先使用 getItem 取出 key 的值,再使用 JSON.parse 把字串解析成陣列可讀的資料 → 物件 ( JSON 格式 ),就可以正常的顯示 farm 陣列中的資料。

  • console.log(typeof(getDataArr)); 查詢從 string 變 object ,為 JSON 格式。這樣就可以正常讀取 var farm 陣列中的資料,這邊用 console.log(getDataArr[0].farmer); 查詢第一筆農夫的資料,成功 !

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    const farm = [
    {farmer:'傑森'}
    ];

    const farmString = JSON.stringify(farm); //把array字串化
    //console.log(farmString);
    localStorage.setItem('farmItem',farmString); //把值帶入key與value

    const getData = localStorage.getItem('farmItem'); //取出 key名為farmItem的value值
    const getDataArr = JSON.parse(getData); //把getData從字串變陣列
    //console.log(typeof(getDataArr)); 查詢var getData型別

    console.log(getDataArr[0].farmer);

data-* 透過 dataset 讀取自訂資料

  • data-** 號可換成自訂名稱,寫於 HTML 中,
    • 監聽時,可使用 e.target.dataset.* 讀取資料。
  • 自訂標籤可以與資料做綁定。
  • 以 ul li 清單標籤舉例,可以於 li 內設定 data-* ,並在資料庫做設定說第幾筆資料要做刪除或其他動作。

範例 1

1
2
3
<ul class="list">
<li data-num="0" data-dog="3" class="listli">卡斯伯</li>
</ul>
  • 程式碼中綁定了 data-numdata-dog ,可於開發者工具讀取者些 data-* 資料 → document.querySelector('.list li').dataset;

  • 也可以查詢單個 data-* 資料,以查詢卡斯伯有幾隻狗為例 → document.querySelector('.list li').dataset.dog;
    截圖

    1
    2
    3
    4
    5
    6
    7
    8
    const list = document.querySelector('.list li');
    list.addEventListener('click', showTex);
    function showTex(e) {
    const num = e.target.dataset.num;
    const dog = e.target.dataset.dog;
    console.log('農夫編號為' + num);
    console.log('農夫養了' + dog + '隻狗。');
    }

❒ dataset、array 運用

範例 1. 把 array 中的資料帶入 ul 中,於畫面顯示農夫名稱

1
<ul class="list"></ul>
1
2
3
4
5
6
7
8
const farm = [
{
farmer: '卡斯伯'
},
{
farmer: '小廝'
}
]

把 li 資料帶入 ul 中

  • 農場資料於 farm 陣列中。

  • 使用 forEach 依序跑出陣列中農夫資料。forEach 的第一個參數為陣列中的每筆物件,第二個參數為索引值,索引值可搭配 data-* 使用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    const farm = [
    {
    farmer: '卡斯伯'
    },
    {
    farmer: '小廝'
    }
    ]
    const list = document.querySelector('.list');
    function renderFarm() {
    let str = '';
    farm.forEach((i, num) => {
    console.log(i);
    str += `<li data-num="${num}">${i.farmer}</li>`
    })
    list.innerHTML = str;
    }
    renderFarm();

點擊 li ,印出對應農夫名稱 ( 使用 querySelector )

  • querySelector 特性只會抓第一筆資料,這時可以選擇它的父層 ul 來做監聽。
  • 指定父層 ul ,使用 e.target 查詢元素去查詢是點擊到 ul 還是 li,因為這邊是想要點擊 li 再做執行,所以可以使用 if 判斷式 → if(e.target.nodeName !== 'LI'){return;}
    • return 可以回傳數值,也可以中斷 function 不執行後方的東西。
    • 可使用 e.target.nodeName 查詢點擊的節點,這邊可使用 console.log(e.target.nodeName) 查看。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
const farm = [
{
farmer: '卡斯伯'
},
{
farmer: '小廝'
}
]
const list = document.querySelector('.list');
function renderFarm() {
let str = '';
farm.forEach((i, num) => {
str += `<li data-num="${num}">${i.farmer}</li>`
})
list.innerHTML = str;
}
renderFarm();

list.addEventListener('click', (e) => {
if (e.target.nodeName !== 'LI') {
return;
}
// renderFarm()中有植入 data-num 使用此方式找到點擊到的農夫位於第幾個索引
let isFarmer = e.target.dataset.num;
// farm[索引值].farmer 可顯示出點擊到的農夫名稱
console.log(farm[isFarmer].farmer);
})

❒ splice 刪除陣列資料

  • 於陣列中刪除指定資料
  • splice(參數1, 參數2)
    • 參數 1 : 起始位置。
    • 參數 2 : 要往後刪除幾筆資料。( 從起始位置開始往後刪除 )

範例 1. 刪除變數 colors 中的 black 與 red 資料

1
const colors =["black" , "red" , "yellow"]
  • const colors =["black" , "red" , "yellow"] 中,第 0 筆資料為 black,第 1 筆資料為 red,第 2 筆資料為 yellow。

    1
    2
    3
    4
    5
    var colors =["black" , "red" , "yellow"]
    //想要刪除索引 0 開始的兩筆資料
    colors.splice(0,2);

    // 最後使用 console.log 查詢可得到變數 colos 剩下 yellow 這筆資料。

    截圖

範例 2. 把 array 中的資料顯示於 ul 內 & 點擊 li 後刪除此 li

1
<ul class="list"></ul>
1
2
3
4
5
6
7
const farm = [
{
farmer: '卡斯伯'
}, {
farmer: '小廝'
}
]

CodePen 範例

Q1. 為什麼 list.addEventListener裡面要再執行一次renderFarmer() ?

因為使用 splice 刪除 farm 陣列中的資料,需要再重新跑一次 farm 陣列中的資料並渲染在畫面中,不然畫面上只會顯示舊的未做刪除的資料。

參考資料

  • 六角學院:JS 入門篇 - 學徒的試煉筆記