30天JS挑战(第十五天)------本地存储菜谱

第十五天挑战(本地存储菜谱)

地址:https://javascript30.com/

所有内容均上传至gitee,答案不唯一,仅代表本人思路

中文详解:https://github.com/soyaine/JavaScript30

该详解是Soyaine及其团队整理编撰的,是对源代码的详解强烈推荐大家观看学习!!!

本人gitee:https://gitee.com/thats-all-right-ha-ha/30-days—js-challenge

效果

在这里插入图片描述

  • 样式分析

    • 组件整体居中,组件内部由头部,菜单主体,菜单添加模块组成
  • 逻辑分析

    • 在输入框输入菜名,点击添加后,菜名在菜单主体内显示

    • 输入框非空限定

    • 点击菜单左侧的多选框,出现选中样式

    • 菜单保存在本地,当页面刷新或关闭后,菜单内容和选中状态不会被重置

本人代码及思路分析

仅提供布局及逻辑代码

结构:

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

逻辑:

//获取元素
const addItems = document.querySelector('.add-items');
const itemsList = document.querySelector('.plates');
const submit = document.querySelector('input[type="submit"]')
const items = JSON.parse(localStorage.getItem('Tapas')) || [];
//页面添加元素 + 本地存储
function addItem(e) {e.preventDefault()const text = document.querySelector('input[type="text"]').valueconsole.log(text)let content = {text,isDone: false}template(content, items.length)items.push(content)localStorage.setItem('Tapas', JSON.stringify(items))this.reset()
}
//模板函数
function template(dom, index) {let check = ''if (dom.isDone) check = 'checked'itemsList.innerHTML += `<li><input type='checkbox' data-index=${index} id='item${index}'  ${check}><label for='item${index}'>${dom.text} </label></li>`
}
//页面初始化
function getItem() {items.forEach((item, index) => {template(item, index)})
}
getItem()
//事件标记,动态存储
function check(e) {const checkbox = document.querySelectorAll('input[type="checkbox"]')const index = e.target.dataset.index console.log(index) if(index || index === 0){items[index].isDone = !items[index].isDonelocalStorage.setItem('Tapas',JSON.stringify(items))}
}
//事件监听
addItems.addEventListener('submit', addItem)
itemsList.addEventListener('click', check)

分析:

  • **整体思路:**当提交事件执行的时候,使用localStorage对输入的内容和内容状态进行本地存储,在页面初始化的时候获取本地存储的数据并进行渲染,

  • 具体实现:

    • 首先选定需要监听和修改的元素
    • addItem
      • 进行提交的时候会对默认对页面进行刷新,先使用e.preventDefault阻止默认事件
      • 获取输入框内的内容,并初始化需要添加的数据,并将数据添加到模板中,通过模板添加到页面中
      • 将数据添加到数组中,再将该数组添加到本地,最后重置表单内容
    • template:构建字符串模板,并初始化元素属性(data-index & item)和选中状态
    • getItem:页面刷新或打开时,获取本地数据,并将他们通过template函数渲染到页面中
    • check:
      • 获取页面中所有的复选框
      • 这里监听的是itemsList父级元素,target会返回父级元素中所包含的所有元素,这里会返回两个元素,分别是label和input
      • 事先定义了data-index作为页面中添加元素的下标,并对其进行了唯一标识
      • 首先判断其是否携带data-index属性来判断其是否是input标签,如果存在那么便从checkbox集合中通过index寻找出对应的被点击的input元素,并对其状态进行动态修改,修改后保存到本地
  • 弊端分析(与官方方法对比):

    • DOM操作频繁: 在模板函数中,每次添加一个待办事项都会重新设置itemsList的innerHTML,这样会引起DOM操作频繁,效率较低。
    • 事件委托不足: 目前勾选完成待办事项的事件监听是直接添加在每个checkbox上的,当待办事项较多时,会导致事件监听器过多,影响性能。应该考虑使用事件委托,将事件监听器添加到父元素上,然后通过事件冒泡来处理。
    • **页面初始化渲染性能开销大:**页面初始化渲染的时候使用的是forEach方法,该方法频繁对页面元素进行增加,消耗性能

官方代码

官方代码仅代表该案例原作者思路,不唯一

结构

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

逻辑

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,done: false};items.push(item);populateList(items, itemsList);localStorage.setItem('items', JSON.stringify(items));this.reset();
}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('');
}function toggleDone(e) {if (!e.target.matches('input')) return; // skip this unless it's an inputconst el = e.target;const index = el.dataset.index;items[index].done = !items[index].done;localStorage.setItem('items', JSON.stringify(items));populateList(items, itemsList);
}addItems.addEventListener('submit', addItem);
itemsList.addEventListener('click', toggleDone);populateList(items, itemsList);

分析

仅代表本人对该代码的分析

建议直接去看Soyaine的中文详解

  • **整体思路:**整体写法与上述保持一致

  • 具体实现:

    • addItem:与上述相比,这里是通过name属性来选择元素
    • toggleDone:这里使用正则的方法对父级元素内的子元素进行过滤,保留input元素
    • populateList:这里使用map方法对添加元素进行整合,最后整体添加到页面中
  • 优点:

    • 通过map方法一次性生成所有待办事项的HTML字符串,然后一次性插入到DOM中,减少了浏览器的重绘和重排次数,但在处理大量数据时仍有优化空间。
    • 第二段代码通过在列表的父元素上监听点击事件,使用了事件委托的策略,这样做可以减少事件监听器的数量,提高性能,尤其是在待办事项数量较多时。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/509065.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL】事务管理 -- 详解

一、前言 CURD 不加控制&#xff0c;会有什么问题&#xff1f; CURD 满足什么属性&#xff0c;能解决上述问题&#xff1f; 买票的过程得是原子的。买票应该不能受互相的影响。买完票应该要永久有效。买前和买后都要是确定的状态。 什么是事务&#xff1f; 事务就是一组 DML…

独立游戏《星尘异变》UE5 C++程序开发日志2——创建并编写一个C++类

在本篇日志中&#xff0c;我们将要用一个C类来实现一个游戏内的物品&#xff0c;同时介绍UCLASS、USTRUCT、UPROPERTY的使用 一、创建一个C类 我们在UE5的"内容侧滑菜单"中&#xff0c;在右侧空白中右键选择"新建C类"&#xff0c;然后可以选择一个想要的…

用什么台灯可以护眼?多款满分护眼台灯实测推荐

在日常生活中台灯的重要性可以说是不言而喻的&#xff0c;不仅能够起到装饰的作用&#xff0c;而且在夜晚学习工作时还能够提供充足的照明&#xff0c;使得我们学习、工作保持极高的专注度。不过台灯也有好坏之分&#xff0c;一些低价的台灯往往通过在一些不易察觉的细节上降低…

用Python拟合两个高斯分布及其在密度函数上的表现

要拟合两个高斯分布并可视化它们的密度函数&#xff0c;您可以使用Python中的scipy.stats模块来拟合分布&#xff0c;并使用matplotlib来绘制密度函数。下面我将演示了如何拟合两个高斯分布并绘制它们的密度函数&#xff1a; 1、问题背景 用Python拟合两个重叠的高斯分布&…

IO 与 NIO

优质博文&#xff1a;IT-BLOG-CN 一、阻塞IO / 非阻塞NIO 阻塞IO&#xff1a;当一条线程执行read()或者write()方法时&#xff0c;这条线程会一直阻塞直到读取到了一些数据或者要写出去的数据已经全部写出&#xff0c;在这期间这条线程不能做任何其他的事情。 非阻塞NIO&…

【比较mybatis、lazy、sqltoy、lambda、操作数据 】操作批量新增、分页查询【一】

orm框架使用Lambda性能比较 环境&#xff1a; idea jdk17 spring boot 3.0.7 mysql 8.0测试条件常规对象 orm 框架是否支持xml是否支持 Lambda对比版本mybatis☑️☑️3.5.4sqltoy☑️☑️5.2.98lazy✖️☑️1.2.3-JDK17 数据库表(含有唯一性索引s_u) CREATE TABLE sys_u…

手机日历怎么设置农历生日提醒?生日提醒倒计时怎么设置?

对我而言&#xff0c;记住每个亲朋好友的生日并在每年的那一天给予他们温馨的祝福&#xff0c;是一种传达爱意和关怀的方式。这不仅能够加深我们之间的情感联系&#xff0c;还能让他们感受到自己的重要性。然而&#xff0c;在繁忙的生活节奏中&#xff0c;有时候我们可能会忘记…

39. 【Linux教程】修改文件所属关系

上一节介绍了如何修改文件的读、写、执行权限&#xff0c;包括属主用户权限、所属用户组权限、其他用户组用户权限&#xff0c;本小节介绍如何修改文件的所属关系&#xff0c;所属关系又包括文件的属主和所属组。 1.chown 命令 若想要修改文件的属主&#xff0c;可以使用 chow…

He3 —— 开发者必备的万能工具箱!

推荐一款巨好用又高效的开发必备神器 —— He3 废话不用多说&#xff0c;官网说明简单直接 &#xff01;官网地址&#xff1a;https://he3app.com/zh/ 非要说这个软件要说有什么不好&#xff0c;可能就是有的人打不开官网吧(DDDD)&#xff0c;不过咱可以在本地安装呀&#xf…

【BUUCTF Misc】通关1.0

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …

明日开展 | 2024济南生物发酵系列展携手全球优质品牌惊艳世界,燃放济南!

明日开展&#xff0c;精彩来袭&#xff01; 2024济南生物发酵系列展 携手全球优质品牌 惊艳世界&#xff0c;燃放济南&#xff01; 2024济南生物发酵系列展&#xff0c;由中国生物发酵产业协会主办&#xff0c;上海信世展览服务有限公司承办&#xff0c;3月5-7日在山东国际…

Linux入门到入土

Linxu Linux 简介 Linux 内核最初只是由芬兰人林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;在赫尔辛基大学上学时出于个人爱好而编写的。 Linux 是一套免费使用和自由传播的类 Unix 操作系统&#xff0c;是一个基于 POSIX&#xff08;可移植操作系统接口&#xff09…