摘要:完整中文版指南及視頻教程在從零到壹全棧部落。當(dāng)頁面重新刷新或者關(guān)閉之前,執(zhí)行清除頁面的緩存。慎用,尤其在生產(chǎn)環(huán)境中。
Day15 - LocalStorage
(Node+Vue+微信公眾號(hào)開發(fā))企業(yè)級(jí)產(chǎn)品全棧開發(fā)速成周末班首期班(10.28號(hào)正式開班,歡迎搶座)
效果圖作者:?黎躍春-追時(shí)間的人
簡介:JavaScript30 是 Wes Bos 推出的一個(gè) 30 天挑戰(zhàn)。項(xiàng)目免費(fèi)提供了 30 個(gè)視頻教程、30 個(gè)挑戰(zhàn)的起始文檔和 30 個(gè)挑戰(zhàn)解決方案源代碼。目的是幫助人們用純 JavaScript 來寫東西,不借助框架和庫,也不使用編譯器和引用?,F(xiàn)在你看到的是這系列指南的第 14 篇。完整中文版指南及視頻教程在 從零到壹全棧部落。
第十五天主要是練習(xí)LocalStorage(本地存儲(chǔ))以及時(shí)間委托的使用,使用場景是一個(gè)簡單的todo list的應(yīng)用,實(shí)現(xiàn)基本的添加item,切換完成狀態(tài),將所有todo項(xiàng)存儲(chǔ)在localstorage中,保證刷新瀏覽器后數(shù)據(jù)不丟失。
主要思路提前預(yù)定義好所有用到的變量;
// 添加item的按鈕 const addItems = document.querySelector(".add-items"); // todolist列表 const itemsList = document.querySelector(".plates"); // 本地緩存的所有todoitem const items = JSON.parse(localStorage.getItem("items")) || [];
為addItems按鈕添加事件函數(shù),添加一個(gè)新的todo item并存儲(chǔ)到本地緩存;
監(jiān)聽checkbox的點(diǎn)擊事件,切換是否完成的狀態(tài),并更新本地存儲(chǔ),保證刷新本頁面是數(shù)據(jù)不會(huì)丟失;
分別設(shè)置兩個(gè)監(jiān)聽器,監(jiān)聽addItems的submit事件,和itemsList的點(diǎn)擊事件;
添加item事件添加item的主要代碼如下
function addItem(e) { // 阻止默認(rèn)事件的觸發(fā),防止在提交后頁面自己刷新 e.preventDefault(); const text = this.querySelector("[name=item]").value; const item = { // ES6的簡寫形式 => text: text; text, done: false }; items.push(item); localStorage.setItem("items", JSON.stringify(items)); populateList(items, itemsList); // 添加完數(shù)據(jù)后,重置輸入框 this.reset(); } addItems.addEventListener("submit", addItem);
監(jiān)聽addItems的submit事件,當(dāng)用戶點(diǎn)擊enter或者點(diǎn)擊右側(cè)的submit按鈕的時(shí)候觸發(fā);
text,是ES6的縮寫形式,即代表text: text;
*localStorage的常用API:
localStorage.setItem(‘key’,value); -> 設(shè)置本地緩存,以key-value的形式
localStorage.getItem(‘key’); -> 根據(jù)參數(shù)key取得本地緩存中對(duì)應(yīng)的值
localStorage.clear(); -> 清空本地的緩存
localStorage.removeItem(‘key’); -> 刪除key所對(duì)應(yīng)的那一條本地緩存
localStorage中只能存儲(chǔ)字符串,所以我們經(jīng)常會(huì)用到: JSON.stringify(object)將一個(gè)對(duì)象轉(zhuǎn)換為字符串,再使用JSON.parse(objSting)將一個(gè)對(duì)象字符串轉(zhuǎn)換為對(duì)象
this.reset();代表將表單重置,清空表單中的值,在我們進(jìn)行了一次submit之后,如果不重置表單的話,表單中的值將不會(huì)消失,這將大大影響用戶體驗(yàn)
切換完成狀態(tài)事件function toggleDone(e) { // if(!e.target.nodeName.match("INPUT")) return; // 跳過所有的input,只處理label if (!e.target.matches("input")) return; const node = e.target; const index = node.dataset.index; items[index].done = !items[index].done; localStorage.setItem("items", JSON.stringify(items)); populateList(items, itemsList); } itemsList.addEventListener("click", toggleDone);
此處使用到了事件委托,所謂事件委托,我是這么理解的:
假設(shè)我們隊(duì)一個(gè)input列表進(jìn)行了事件監(jiān)聽,但我們?nèi)绶ūWC,此列表在接下來的狀態(tài)下是否進(jìn)行了更新,刷新等改變?cè)瓉砉?jié)點(diǎn)的操作,如果有這樣的操作出現(xiàn),那么我們之前的事件監(jiān)聽器就無法再起到監(jiān)聽的作用;
但我們可以對(duì)input列表的父元素進(jìn)行事件監(jiān)聽,讓它們的父元素處于監(jiān)聽狀態(tài),當(dāng)我們所點(diǎn)擊的元素是其子元素的話,就告訴它的子元素,執(zhí)行相應(yīng)的事件;
相當(dāng)于委托父元素幫我們監(jiān)聽所有子元素,這樣無論子元素列表進(jìn)行怎么樣的更新,改變,只要父元素節(jié)點(diǎn)不發(fā)生改變就可以持續(xù)起到監(jiān)聽的 作用。
通過e.target.matches("input")可以判斷所點(diǎn)擊的元素是不是input元素,e.target返回所點(diǎn)擊的宿主元素。
通過獲取到所點(diǎn)擊的列表的序號(hào),更改其done屬性,更新后進(jìn)行存儲(chǔ),就可以實(shí)現(xiàn)完成狀態(tài)的事件。
列表顯示函數(shù)// 設(shè)置默認(rèn)值,防止傳參數(shù)出錯(cuò)的時(shí)候crash function populateList(populates = [], place { place.innerHTML = populates.map((populate, index) => { //之所以用‘’空字符是因?yàn)槿绻胣ull的話,會(huì)出現(xiàn)在html中 return `
將所有的列表項(xiàng)轉(zhuǎn)化為li傳入頁面的html中
將此函數(shù)抽象出來,以方便以后實(shí)現(xiàn)同樣類似的操作,將一個(gè)數(shù)組中的元素動(dòng)態(tài)添加到頁面的一個(gè)節(jié)點(diǎn)中
清除緩存// 在關(guān)閉瀏覽器之后清除緩存 window.onbeforeunload = function (e) { localStorage.removeItem("items"); // let confirmationMessage = "o/"; e.returnValue = confirmationMessage; // Gecko, Trident, Chrome 34+ // return confirmationMessage; // 如果有返回值的話,就會(huì)彈出確認(rèn)框。 };
有些時(shí)候,我們僅僅是為了練習(xí)localStorage的使用,并不想在瀏覽器中留下過多的緩存,那么這個(gè)方法就派上了用場。
當(dāng)頁面重新刷新或者關(guān)閉之前,執(zhí)行localStorage.removeItem("items’);清除頁面的緩存。
慎用,尤其在生產(chǎn)環(huán)境中。
整體代碼架構(gòu)const addItems = document.querySelector(".add-items"); const itemsList = document.querySelector(".plates"); const items = JSON.parse(localStorage.getItem("items")) || []; function addItem(e) { e.preventDefault(); const text = this.querySelector("[name=item]").value; const item = { text, // ES6的簡寫形式 => text = text; done: false }; items.push(item); localStorage.setItem("items", JSON.stringify(items)); populateList(items, itemsList); this.reset(); // 添加完數(shù)據(jù)后,重置輸入框 } function populateList(populates = [], place) { // 設(shè)置默認(rèn)值,防止傳參數(shù)出錯(cuò)的時(shí)候crash place.innerHTML = populates.map((populate, index) => { return `
在頁面加載的時(shí)候,先獲取本地緩存的items,若存在就傳給變量items,若第一次登錄或者無item,初始化為空數(shù)組;
在頁面加載的時(shí)候先加載頁面的所有todolist,執(zhí)行一遍populateList(items, itemsList);函數(shù)即可。
Github Source Code
全棧部落 | 區(qū)塊鏈部落 |
---|---|
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/84640.html
摘要:加入我們,一起挑戰(zhàn)吧掃碼申請(qǐng)加入全棧部落 JavaScript 30 - 一起做一次了不起的挑戰(zhàn) (Node+Vue+微信公眾號(hào)開發(fā))企業(yè)級(jí)產(chǎn)品全棧開發(fā)速成周末班首期班(10.28號(hào)正式開班,歡迎搶座) 在Github上看到了wesbos的一個(gè)Javascript30天挑戰(zhàn)的repo,旨在使用純JS來進(jìn)行練習(xí),不允許使用任何其他的庫和框架,該挑戰(zhàn)共30天,我會(huì)在這里復(fù)現(xiàn)這30天遇到的挑...
摘要:最后就是用各種的數(shù)據(jù)進(jìn)行判斷,渲染。否則任務(wù)的完成時(shí)間會(huì)出錯(cuò),導(dǎo)致頁面渲染錯(cuò)誤。組件正在開發(fā)中,后期會(huì)分享,缺少彈窗提示,這里的操作動(dòng)作很多,完全可以開發(fā)一個(gè)彈窗組件,方便用。 一,demo背景: 1,可以熟悉原生js 2,平時(shí)不知道自己學(xué)完js要做些什么東西的小伙伴 3,自己寫的,可以當(dāng)做自己的作品 4,為廣大想練習(xí)練習(xí)原生js的貢獻(xiàn)一個(gè)素材 二,實(shí)現(xiàn)功能: 1,新建/刪除任務(wù)...
摘要:最后就是用各種的數(shù)據(jù)進(jìn)行判斷,渲染。否則任務(wù)的完成時(shí)間會(huì)出錯(cuò),導(dǎo)致頁面渲染錯(cuò)誤。組件正在開發(fā)中,后期會(huì)分享,缺少彈窗提示,這里的操作動(dòng)作很多,完全可以開發(fā)一個(gè)彈窗組件,方便用。 一,demo背景: 1,可以熟悉原生js 2,平時(shí)不知道自己學(xué)完js要做些什么東西的小伙伴 3,自己寫的,可以當(dāng)做自己的作品 4,為廣大想練習(xí)練習(xí)原生js的貢獻(xiàn)一個(gè)素材 二,實(shí)現(xiàn)功能: 1,新建/刪除任務(wù)...
摘要:最后就是用各種的數(shù)據(jù)進(jìn)行判斷,渲染。否則任務(wù)的完成時(shí)間會(huì)出錯(cuò),導(dǎo)致頁面渲染錯(cuò)誤。組件正在開發(fā)中,后期會(huì)分享,缺少彈窗提示,這里的操作動(dòng)作很多,完全可以開發(fā)一個(gè)彈窗組件,方便用。 一,demo背景: 1,可以熟悉原生js 2,平時(shí)不知道自己學(xué)完js要做些什么東西的小伙伴 3,自己寫的,可以當(dāng)做自己的作品 4,為廣大想練習(xí)練習(xí)原生js的貢獻(xiàn)一個(gè)素材 二,實(shí)現(xiàn)功能: 1,新建/刪除任務(wù)...
因?yàn)楣ぷ髦薪?jīng)常用到這些方法,所有便把這些方法進(jìn)行了總結(jié)。 JavaScript 1. type 類型判斷 isString (o) { //是否字符串 return Object.prototype.toString.call(o).slice(8, -1) === String } isNumber (o) { //是否數(shù)字 return Object.prototype.to...
閱讀 2806·2023-04-26 02:02
閱讀 2677·2023-04-25 20:38
閱讀 4264·2021-09-26 09:47
閱讀 3186·2021-09-10 10:50
閱讀 3859·2021-09-07 09:58
閱讀 3390·2019-08-30 15:54
閱讀 2761·2019-08-30 15:54
閱讀 1986·2019-08-29 17:03