iT邦幫忙

2022 iThome 鐵人賽

DAY 15
0
自我挑戰組

JavaScript 30天挑戰 自學筆記系列 第 15

JS30 自學筆記 Day15_LocalStorage and Event Delegation

  • 分享至 

  • xImage
  •  

不知不覺完成第15天了,繼續加油!


今日任務: 做一個菜單,可以新增東西進去,重新整理後也不會不見

HTML部分

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

JS部分

items是儲存菜色(資料)用

const addItems = document.querySelector('.add-items');
const itemsList = document.querySelector('.plates');
const items = [];

submit 事件會在表單送出時觸發,
這樣不管是按enter還是用滑鼠按button都會觸發

addItems.addEventListener('submit', addItem);

function addItem() {
    console.log(123);
}

測試,因為按下submit會refresh頁面,可以看到會很快地閃123
保留紀錄 Preserve log
跳轉頁面的時候勾選上,可以看到之前的請求,也可以適用於chrome開發者抓問題

Event.preventDefault()

取消事件的預設行為
submit預設會refresh頁面,我們不想要refresh頁面,所以加上e.preventDefault()

function addItem(e) {
    e.preventDefault();
}

這裡的this是整個form,所以可以直接獲取裡面的dom

function addItem(e) {
    e.preventDefault();
    console.log(this);
}

獲取輸入的文字,做成一個item

function addItem(e) {
    e.preventDefault();
    const text = this.querySelector('[name= item]').value;
    const item = {
        text, //text:text簡寫
        done: false,
    };
    console.log(item);
}

輸入文字後渲染畫面,並清空input

reset()可以重製表單,清空input

items.push(item);
this.reset();

plates預設為空陣列,避免忘記傳參數導致map()壞掉
map()後會回傳一個陣列,因為我們要放入html,所以加上.join()轉成字串,
並判斷plate.done,true的話就加上checked

function addItem(e) {
    e.preventDefault();
    const text = this.querySelector('[name= item]').value;
    const item = {
        text, //text:text簡寫
        done: false,
    };
    items.push(item);
    renderPlates(items, itemsList);
    this.reset();
}

function renderPlates(plates = [], platesList) {
   platesList.innerHTML = plates
      .map((plate, i) => {
        return `<li>
        <input type="checkbox" id="item${i}" data-index="${i}" ${plate.done ? 'checked' : ''}>
        <label for="item${i}">${plate.text}</label>
        </li>`;
    }).join('');
}

LocalStorage,重新整理後資料會還在

HTML5提供兩種在客戶端儲存資料的方法,彌補了cookie儲存量小、不適用於大量資料本地儲存的問題。

sessionStorage / localStorage:

  • 儲存資料方式為 key 和 value
  • key和value皆為字串型式(請留意, 當其為物件、 整數等將自動轉換為字串型式)
  • 大小預設有 5mb
  • sessionStorage: 當網頁關閉時,資料就會清除。
  • localStorage: 資料永久存在,唯有清除它才會消失。

localStorage使用方法:

  • localStorage.setItem('key(名字)', 要存進去的東西)
  • localStorage.getItem('key(名字)', 要拿出來的東西)
localStorage.setItem('items', items);

但是長這樣

因為存入物件的時``候,瀏覽器會自動轉換為字串toString()
所以我們自己先stringify()轉換為 JSON 字符串
之後取得時再parse()就可以轉回來用

 localStorage.setItem('items', JSON.stringify(items));

可以儲存了

頁面一進來先從LocalStorage拿東西,然後渲染

const items = JSON.parse(localStorage.getItem('items')) || [];
renderPlates(items, itemsList);

事件委派(Event Delegation)

最後我們要監聽被勾選的item,並將打勾狀態存進localStorage中
直覺上,會直接在checkbox上監聽是否勾選:

renderPlates(items, itemsList);
const checkboxes = document.querySelectorAll('input[type="checkbox"]');
console.log(checkboxes);
checkboxes.forEach((checkbox) => 
    checkbox.addEventListener('click', () => console.log(111111)
));

但當我們新增list的時候,這個新增的 list 裡面的checkbox就不會被綁定到事件
所以,我們可以監聽父層: <ul class="plates">
這種做法就叫做事件委派(Event Delegation)

事件委派(Event Delegation)的好處:

  • 減少過多的監聽器
  • HTML 結構靈活,我們可以隨時添加/刪除元素。

比對e.target

ul裡面包括了list、input、label,我們只要點擊到checkbox的才執行
所以比對使用者點到的元素(e.target),
如果不是點到input,就直接return不執行這個函式

const itemsList = document.querySelector('.plates');
itemsList.addEventListener('click', toggleDone);
 
function toggleDone(e) {
    //不是點到input,就直接return不執行這個函式
    if (!e.target.matches('input')) return;
    console.log(e.target);
}

可以根據dataset.index索引值知道我們按的是哪一個,將他變相反的狀態
並存入LocalStorage後渲染

function toggleDone(e) {
    //不是點到input,就直接return不執行這個函式
    if (!e.target.matches('input')) return;
    const el = e.target;
    const index = el.dataset.index;
    items[index].done = !items[index].done;
    localStorage.setItem('item', JSON.stringify(items));
    renderPlates(items, itemsList);
}

今日學習到的:

  • submit 事件會在表單送出時觸發。
  • 保留紀錄 Preserve log,可以看到跳轉頁面之前的請求
  • Event.preventDefault(): 取消事件的預設行為
  • reset(): 可以重製表單,清空input
  • sessionStorage: 當網頁關閉時,資料就會清除
  • localStorage: 資料永久存在,唯有清除它才會消失
  • localStorage.setItem(‘key(名字)’, 要存進去的東西)
  • localStorage.getItem(‘key(名字)’, 要拿出來的東西)
  • 事件委派(Event Delegation): 監聽父層,減少過多的監聽器,增加程式碼的彈性

效果連結:連結

參考連結:
MDN: Window.localStorage
五倍紅寶石: 認識瀏覽器的神秘儲存空間 - localStorage
前端工程師學習手冊: Cookie、LocalStorage、SessionStorage
javascript.info: Event delegation


上一篇
JS30 自學筆記 Day14_Object and Arrays - Reference VS Copy
下一篇
JS30 自學筆記 Day16_CSS Text Shadow Mouse Move Effect
系列文
JavaScript 30天挑戰 自學筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言