[JS30] Day15: LocalStorage and Event Delegation
這堂課我們要學習用 localStorage 儲存資料狀態,以及 event delegation 如何賦予新建立的元素工作。
HTML
有兩個 input,一個輸入文字,一個提交表單,我們要將提交的資訊放入.plates 裡面的<li>
<div class="wrapper">
<h2>LOCAL TAPAS</h2>
<p></p>
<ul class="plates">
<li>Loading Tapas...</li>
</ul>
<form class="add-items">
<input type="text" name="item" placeholder="Item Name" required />
<input type="submit" value="+ Add Item" />
</form>
</div>
JavaScript
選取元素
const addItems = document.querySelector(".add-items");
const itemsList = document.querySelector(".plates");
提交表單時要存入東西
在表單 submit 時,預設會進行重新整理,透過preventDefault擋住,儲存<input>輸入的內容在 itmes 內,要有 text 跟 done 兩個屬性。最後透過 reset 重置<input>
const items = [];
function addItem(e) {
e.preventDefault();
const text = this.querySelector("[name=item]").value;
const item = {
text: text,
done: false,
};
items.push(item);
this.reset();
}
addItems.addEventListener("submit", addItem);
把東西放進清單之中
剛剛存入 items 內的東西,我們要放入清單之中,這邊將次序(i)存入每個<li>元素的data-index,方便之後的勾選。
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("");
}
勾選與否(event delegation)
由於我們一開始沒有任何<li>元素,所以我們要在他的母層使用監聽器,監聽典擊事件,如果該事件的對象剛好是<input/>元素,那我們就要透過他dataset裡面的 index,勾選與否對應 items[index]的 done 屬性,再透過populateList重新加東西放進清單之中。
function toggleDone(e) {
if (!e.target.matches("input")) return;
const el = e.target;
const index = el.dataset.index;
console.log(el.dataset.index);
items[index].done = !items[index].done;
populateList(items, itemsList);
}
itemsList.addEventListener("click", toggleDone);
localStorage 解決重新整理清單不見的問題
我們需要在資料有變化的時候將 items 物件存進 localStorage,一個是在提交表單時(addItem),一個是在修改勾選與否的時候(toggleDone)
localStorage.setItem("items", JSON.stringify(items));
透過setItem我們存入以下內容,可以透過檢查(F12)內的 application->storage->Local Storage 找到

而我們也要在 js 檔一開始透過getItem的方法拿回資料來顯示,並先執行一次populateList放入清單。
const items = JSON.parse(localStorage.getItem("items")) || [];
populateList(items, itemsList);
參考資料
- localStorage @MDN