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.rhkb.cn/news/268886.html

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

相关文章

Java---文件,流✨❤️

文章目录 1.遍历文件夹2.遍历子文件夹3.练习流4.以字节流的形式读取文件内容5.以字节流的形式向文件写入数据顶折纠问6 .写入数据到文件 1.遍历文件夹 一般说来操作系统都会安装在C盘&#xff0c;所以会有一个 C:\WINDOWS目录。 遍历这个目录下所有的文件(不用遍历子目录) 找出…

【数仓】Hadoop软件安装及使用(集群配置)

一、环境准备 1、准备3台虚拟机 Hadoop131&#xff1a;192.168.56.131Hadoop132&#xff1a;192.168.56.132Hadoop133&#xff1a;192.168.56.133 本例系统版本 CentOS-7.8&#xff0c;已安装jdk1.8 2、hosts配置&#xff0c;关闭防火墙 vi /etc/hosts添加如下内容&#x…

#WEB前端(浮动与定位)

1.实验&#xff1a; 2.IDE&#xff1a;VSCODE 3.记录&#xff1a; float、position 没有应用浮动前 应用左浮动和右浮动后 应用定位 4.代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><me…

AIGC下一步:如何用AI再度重构或优化媒体处理?

让媒资中“沉默的大多数”再次焕发光彩。 邹娟&#xff5c;演讲者 编者按 AIGC时代下&#xff0c;媒体内容生产领域随着AI的出现也涌现出更多的变化与挑战。面对AI的巨大冲击&#xff0c;如何优化或重构媒体内容生产技术架构&#xff1f;在多样的应用场景中媒体内容生产技术又…

【EAI 027】Learning Interactive Real-World Simulators

Paper Card 论文标题&#xff1a;Learning Interactive Real-World Simulators 论文作者&#xff1a;Mengjiao Yang, Yilun Du, Kamyar Ghasemipour, Jonathan Tompson, Leslie Kaelbling, Dale Schuurmans, Pieter Abbeel 作者单位&#xff1a;UC Berkeley, Google DeepMind, …

获取 Windows 通知中心弹窗通知内容(含工具汉化)

目录 前言 技术原理概述 测试代码和程序下载连接 本文出处链接&#xff1a;https://blog.csdn.net/qq_59075481/article/details/136440280。 前言 从 Windows 8.1 开始&#xff0c;Windows 通知现在以 Toast 而非 Balloon 形式显示&#xff08; Bollon 通知其实现在是应用…

中小型水库安全监测运营解决方案,筑牢水库安全防线

我国水库大坝具有“六多”的特点。第一&#xff0c;总量多。我国现有水库9.8万座&#xff0c;是世界上水库大坝最多的国家。第二&#xff0c;小水库多。我国现有水库中95%的水库是小型水库。第三&#xff0c;病险水库多。 目前&#xff0c;在我国水库管理中&#xff0c;部分地方…

异常网络下TCP的可靠服务机制(慢启动、拥塞避免、快重传、快恢复)

目录 TCP超时重传拥塞控制概述慢启动和拥塞避免下面讲解发送端如何判断拥塞发生。 快速重传和快速恢复 本文描述TCP在异常网络下的处理方式 以保证其可靠的数据传输的服务 TCP超时重传 tcp服务能够重传其超时时间内没有收到确认的TCP报文段&#xff0c;tcp模块为每一个报文段都…

认识通讯协议——TCP/IP、UDP协议的区别,HTTP通讯协议的理解

目录 引出认识通讯协议1、TCP/IP协议&#xff0c;UDP协议的区别2、HTTP通讯协议的讲解 Redis冲冲冲——缓存三兄弟&#xff1a;缓存击穿、穿透、雪崩缓存击穿缓存穿透缓存雪崩 总结 引出 认识通讯协议——TCP/IP、UDP协议的区别&#xff0c;HTTP通讯协议的理解 认识通讯协议 …

【脑科学相关合集】有关脑影像数据相关介绍的笔记及有关脑网络的笔记合集

【脑科学相关合集】有关脑影像数据相关介绍的笔记及有关脑网络的笔记合集 前言脑模板方面相关笔记清单 基于脑网络的方法方面数据基本方面 前言 这里&#xff0c;我将展开有关我自己关于脑影像数据相关介绍的笔记及有关脑网络的笔记合集。其中&#xff0c;脑网络的相关论文主要…

分享:大数据信用报告查询的价格一般要多少钱?

现在很多人都开始了解自己的大数据信用了&#xff0c;纷纷去查大数据信用报告&#xff0c;由于大数据信用与人行征信有本质的区别&#xff0c;查询方式和价格都不是固定的&#xff0c;本文就为大家详细讲讲大数据信用报告查询的价格一般要多少钱&#xff0c;希望对你有帮助。 大…

用Java语言创建的Spring Boot项目中,如何传递数组呢??

问题&#xff1a; 用Java语言创建的Spring Boot项目中&#xff0c;如何传递数组呢&#xff1f;&#xff1f; 在这个思路中&#xff0c;其实&#xff0c;Java作为一个后端开发的语言&#xff0c;没必要着重于如何传入&#xff0c;我们主要做的便是对传入的数组数据进行处理即可…

Vue开发实例(十一)用户列表的实现与操作

用户列表的实现与操作 一、创建用户页面和路由二、表格优化1、表头自定义2、表格滚动3、加入数据索引4、利用插槽自定义显示 三、功能1、查询功能3、增加4、删除5、修改 一、创建用户页面和路由 创建用户页面 在 src/components/Main 下创建文件夹user&#xff0c;创建文件Us…

从零开始搭建web组态

成果展示&#xff1a;by组态[web组态插件] 一、技术选择 目前只有两种选择&#xff0c;canvas和svg Canvas: 是一个基于像素的渲染引擎&#xff0c;使用JavaScript API在画布上绘制图像&#xff0c;它的优点包括&#xff1a; Canvas渲染速度快&#xff0c;适合处理大量图像和…

数据结构从入门到精通——链表

链表 前言一、链表1.1 链表的概念及结构1.2 链表的分类1.3 链表的实现1.4 链表面试题1.5 双向链表的实现 二、顺序表和链表的区别三、单项链表实现具体代码text.htext.cmain.c单链表的打印空间的开辟链表的头插、尾插链表的头删、尾删链表中元素的查找链表在指定位置之前、之后…

公网IP怎么获取?

公网IP是网络中设备的唯一标识符&#xff0c;用于在Internet上进行通信和定位。对于普通用户来说&#xff0c;了解如何获取自己的公网IP是很有必要的&#xff0c;本文将介绍几种获取公网IP的方法。 方法一&#xff1a;通过路由器查询 大多数家庭和办公室使用的路由器都会有一个…

php httpfs链接hdfs

一.代码&#xff08;有bug&#xff09; GitHub - michaelbutler/php-WebHDFS: A PHP client for WebHDFS 二.调用代码 1.代码1.代码 require_once(../webhdfs/src/org/apache/hadoop/WebHDFS.php);require_once(../webhdfs/src/org/apache/hadoop/tools/Curl.php); require_o…

Machine Vision Technology:Lecture2 Linear filtering

Machine Vision Technology&#xff1a;Lecture2 Linear filtering Types of ImagesImage denoising图像去噪Defining convolution卷积的定义Key properties卷积的关键属性卷积的其它属性Annoying details卷积练习Sharpening锐化Gaussian KernelNoise噪声 分类Gaussian noise高…

一篇了解电阻的使用

目录 一、电阻理论基础 1.电阻的定义 2.欧姆定律 3.电阻决定式 4.电阻的串并联​编辑 5.电阻的功率 6.温度对电阻的影响 二、电阻的选型 1.安装方式 2.电阻值 &#xff08;1&#xff09;电阻值的标称 &#xff08;2&#xff09;电阻值的确定 &#xff08;3&#x…

如何在Linux使用Docker部署Redis并结合内网穿透实现公网远程连接本地数据库

文章目录 前言1. 安装Docker步骤2. 使用docker拉取redis镜像3. 启动redis容器4. 本地连接测试4.1 安装redis图形化界面工具4.2 使用RDM连接测试 5. 公网远程访问本地redis5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定TCP地址远程访问 正文开始前给大家推荐个网站…