「JavaScript 30」學習筆記(十五)

前言

本文為「JavaScript 30」教學影片的學習筆記。

目標

使用 Local Storage 儲存選單內容。

筆記

取得相關元素。

1
2
3
4
5
6
// 取得表單元素
const addItems = document.querySelector('.add-items');
// 取得選單元素
const itemsList = document.querySelector('.plates');
// 從 Local Storage 取得 items 陣列或設置為一個空陣列
const items = JSON.parse(localStorage.getItem('items')) || [];

新增一個 addItem() 方法,以新增項目。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function addItem(e) {
// 防止提交表單之後頁面刷新
e.preventDefault();
// 取得表單輸入框的値
const text = (this.querySelector('[name=item]')).value;
// 設置一個 item 物件
const item = {
text: text,
done: false
};
// 將 item 物件推進 items 陣列
items.push(item);
// 將 items 陣列改寫為選單,並重寫選單元素
populateList(items, itemsList);
// 將 items 陣列轉換為字串存入 Local Storage
localStorage.setItem('items', JSON.stringify(items));
// 提交表單後重置
this.reset();
}

新增一個 populateList() 方法,以改寫選單。

1
2
3
4
5
6
7
8
9
10
11
function populateList(plates = [], platesList) {
// 將陣列的每一個物件改寫為選單項目
platesList.innerHTML = plates.map((plate, i) => {
return `
<li>
<input type="checkbox" data-index=${i} id="item${i}" ${plate.done ? 'checked' : ''} />
<label for="item${i}">${plate.text}</label>
</li>
`
}).join('');
}
  • map() 方法會建立一個新的陣列,其內容為原陣列的每一個元素經由回呼函式運算後所回傳的結果之集合。
  • join() 方法會將陣列(或類陣列物件)中所有的元素連接、合併成一個字串,並回傳此字串。

新增一個 toggleDone() 方法,以切換核取方塊狀態。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function toggleDone(e) {
// 如果觸發事件的元素不是 input 就跳過
if (!e.target.matches('input')) return;
// 取得輸入框元素
const el = e.target;
// 取得輸入框元素 data-index 的値
const index = el.dataset.index;
// 將被選取的輸入框的 done 屬性反轉
items[index].done = !items[index].done;
// 將 items 陣列轉換為字串存入 Local Storage
localStorage.setItem('items', JSON.stringify(items));
// 將 Local Storage 的 items 陣列改寫為選單,並重寫選單元素
populateList(items, itemsList);
}

監聽表單元素,如果發生 submit 事件,就觸發 addItem() 方法。

1
addItems.addEventListener('submit', addItem);

監聽選單元素,如果發生 click 事件,就觸發 toggleDone() 方法。

1
itemsList.addEventListener('click', toggleDone);

不管有無動作,將 Local Storage 的 items 陣列改寫為選單,並重寫選單元素。

1
populateList(items, itemsList);