第15天的實作是要利用LocalStorage來讓網頁關閉之後,資料不會移除,讓資料一直儲存在電腦中,以及Event Delegation。
在頁面表單可以輸入,因此在表單建立submit
的事件,但是submit
會造成畫面重整,因此要加入preventDefault()來取消submit
事件觸發時造成的重整。
e.preventDefault();
此時的目標是當表單輸入完成後,觸發submit
事件,讓畫面新增輸入的內容放置於ul
元素中。
資料的內容包含輸入值以及輸入狀態,輸入狀態的內容為布林值。
const item = {
name: this.querySelector('[name=item]').value,
isDone: false,
}
接下來是將表單中資料push
到陣列中,再將陣列資料轉換為實體元素。
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('');
在動態建立的元素中以li
包裹著兩個元素input[checkbox]
,label
,因接下來透過input[checkbox]
的點選來改變資料的狀態。
但此時發現重整畫面ul
中的資料會消失,因此透過localStorage
將資料存入,避免重整頁面而產生資料消失。
這時會發現直接將資料存入localStorage
中會變成object
格式,因此透過JSON.stringify()
的方式轉換成文字,在儲存到localStorage
中。
localStorage.setItem('items', JSON.stringify(items));
之後再取得localStorage
資料要用JSON.parse()
轉換成物件。
const items = JSON.parse(localStorage.getItem('items')) || [];
接下來是建立click
點選input[checkbox]
即改變資料狀態的事件。
itemsList.addEventListener('click', toggleItem)
但此時會發現初始化所建立的li
會有事件被觸發,但後來動態新增的li
元素沒法觸發click
事件。
原因是建立元素時是透過Element.innerHTML
來加入內容,innerHTML
是在該元素加入內容,但內容卻沒有包含事件。
為避免這問題的發生,就使用Event Delegation來作為解答」[1][2]。
Event Delegation的方式是指定在共同父層建立事件,當事件被觸發時,再去判斷為哪一個子元素被事件改變。
所先在事件中要先判斷是否符合input
元素,若不是input
元素則結束事件。
之後取得觸發事件的元素,並使用dataset
取得index
值,用index
值來改變點選的狀態,再儲存轉換後的資料。
function toggleItem(e) {
if (!e.target.matches('input')) return
const el = e.target
const index = el.dataset.index
items[index].isDone = !items[index].isDone
localStorage.setItem('items', JSON.stringify(items))
showList(items, itemsList)
}
<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>
Window.localStoragelocalStorageg
類似於sessionStorage
,但localStorageg
可以不會有過時效,但sessionStorage
網頁關閉時其資料內容會被完全清除。
Window.sessionStoragesessionStorage
這個屬性讓開發人員將資料暫存在當下頁面(頁籤)的空間Storage物件裡。sessionStorage
跟Window.localStorage
很相似,唯一不同的地方是存放在localStorage的資料會永久保存,存放在sessionStorage
的資料則會在頁面(頁籤)關閉時清空。只要該頁面頁面(頁籤)沒被關閉或者有還原(restore)該頁面,資料就會保存。
Event.preventDefault()
如果事件可以被取消,就取消事件(即取消事件的預設行為)。但不會影響事件的傳遞,事件仍會繼續傳遞。
Event.target
指向最初觸發事件的 DOM 物件。
HTMLFormElement
HTMLFormElement 介面提供了建立及修改 <form>
元素的方法。
HTMLFormElement.reset()
reset()方法將form
元素中的內容回復成預設值。
HTMLFormElement.submit()
submit()方法提交form
中的資料。
box-sizing
box-sizing 屬性用於更改預設 CSS 盒子模型 中所計算的寬度和高度。
content-box
這是根據 CSS 標準的起始值和預設值。 width 與 height 只包括內容本身的寬和高, 不包括邊框(border)、內邊距(padding)、外邊距(margin)。注意:內邊距、邊框和外邊距都在這個盒子的外部。
border-box
width 和 height 屬性包括內容(content),內邊距(padding)和邊框(border),但不包括外邊距(margin)。
localStorage
, Event delegation