iT邦幫忙

1

JS30 Day 15 - LocalStorage學習筆記

  • 分享至 

  • xImage
  •  

這次做得功能類似to do list,不過只有增加及改變狀態的功能。

https://ithelp.ithome.com.tw/upload/images/20200707/20126182hwEXs2ao8d.png

在開始之前我們需要先大致了解,本地的資料庫也就是F12=>Application下的Storage。

Local storage(大小5-10M):

也是我們今天的重點,簡而言之就是本地儲存庫,格式為 key : value只能記較單純的資料類型,如數值、字串可以跨瀏覽器分頁做使用、使用者關掉分頁或瀏覽器再打開資料仍不會消失,且資料無期效限制,資料將永久被保留,除非我們手動作刪除

cookie(大小約 4kb):

由於HTTP協定是無狀態的概念,所以Server處理完我們的資料就不會記得我們所做的紀錄、事情等,如我們在購物車購買東西,但是Server並不會知道我們買了什麼,此時就需要cookie,而cookie是由Web server端產生的,作為發送给browser端,而當browser接收到Cookie後,會將其中的key/value保存到某個路徑內的文本文件之中,讓下次於造訪同一網站時,就可以將Cookie自動發送给Web Server端,像是local與server在交換時會帶有的內容,會在驗證、登入、購物車等情境下使用到

Session storage:

與session不同,session是存在server端Session storage存在本地端,存在檔案或資料庫,搭配cookie使用,生命週期較短,當使用者關掉瀏覽器或分頁時,sessionStorage 中的資料將被清空

首先就是獲取我們會用到的DOM元素,其中localStorage的資料獲取需要透過getItem getItem(keyName);,且獲取的型態為字串,所以要parse轉為JSON型式([{},{}...]),預設值為空陣列。

    const addItems = document.querySelector('.add-items');
    const itemsList = document.querySelector('.plates');
    // 利用getItem獲取localStorage中的資料
    const items = JSON.parse(localStorage.getItem('items')) || [];

增添事件處理

    // 送出增加列表事件
    addItems.addEventListener('submit', addItem);
    // 點擊列表狀態切換事件
    itemsList.addEventListener('click', toggleDone);

    createList(items, itemsList);

而增添事件的函數,是採submit觸發,由於submit本身會有預設的動作,如跳轉到指定網址等,所以一開始需要加上e.preventDefault()來避免預設行為,而後value是利用屬性篩選器來獲取(form底下有name="item"的DOM元素),
接著我們在將資料的值及狀態(done)以物件型式儲存。

而後push至我們的localStorage的資料陣列中,並利用setItem(setItem(keyName, keyValue);),來更新我們的localStorage資料,且記得將我們已轉為JSON型式的資料字串化,因為要傳回localStorage,而localStorage的資料都是以字串型式表示。

而這邊還使用了一個清除在form下input中value的一個方法,HTMLFormElement.reset(),可清除表單內的資料

    // 在表單輸入資料並點擊增加之處理
    function addItem(e) {
      // 防止submit的預設行為(跳轉頁面...)
      e.preventDefault();
      // let value = this.querySelector('input:first-child').value;
      let value = (this.querySelector('[name=item]')).value;
      const obj = {
        value,
        done: false
      };
      // 將input輸入之資料push進陣列(更新)
      items.push(obj);
      // 更新Local資料
      localStorage.setItem(
        "items",
        // 記得將資料字串化
        JSON.stringify(items)
      );
      createList(items, itemsList); // 呼叫產生list(更新畫面)
      // HTMLFormElement.reset() 可清除表單內的資料
      this.reset();
      // this.querySelector('[name=item]').value = "";
    }

下面為產生列表的函數,記得最後要做join將 , 去除以空字串來隔開每筆資料。


    // 第一個參數為資料,data=[]的用意,為賦予一個[]表示為預設值
    // 第二個參數為我們要放置進去的DOM
    function createList(data = [], platesList) {
      // 將陣列中的物件拿出來處理 
      // 第一個參數為物件資料
      // 第二個為下標
      platesList.innerHTML = data.map((plate, index) => {
        return `
        <li>
          <input type="checkbox" data-index=${index} id="item${index}" ${plate.done ? 'checked' : ''} />
          <label for="item${index}">${plate.value}</label>
        </li>
      `;
      }).join('');
    }

切換狀態處理函數,由於target因為label的特性會觸發兩次,故我們利用matches來判斷目標是否為input, (element.matches(selectorString); 可檢查元素是否為指定選擇器,是返回true,反之false),來判斷是否要繼續執行,而後在對應的列表進行狀態切換,最後別忘記更新我們的localStorage及畫面。


    function toggleDone(e) {
      console.log(e.target, e.currentTarget); // 發現target會重複觸發
      // 判斷是否為Input,是的話才繼續(避免會重複觸發)
      if (!e.target.matches('input')) return; // skip this unless it's an input
      const el = e.target;
      // 自定義屬性為data-index的DOM
      const index = el.dataset.index;
      // 切換其DOM的done狀態
      items[index].done = !items[index].done;
      // 更新local資料庫
      localStorage.setItem('items', JSON.stringify(items));
      // 更新畫面
      createList(items, itemsList);
    }
    

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言