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"]').value
  console.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].isDone
    localStorage.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 input
  const 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.mfbz.cn/a/426706.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构】B树

1 B树介绍 B树&#xff08;英语&#xff1a;B-tree&#xff09;&#xff0c;是一种在计算机科学自平衡的树&#xff0c;能够保持数据有序。这种数据结构能够让查找数据、顺序访问、插入数据及删除的动作&#xff0c;都在对数时间内完成。B树&#xff0c;概括来说是一个一般化的…

CAS外部云迁移vmware虚拟机兼容性问题处理

CAS外部云迁移vmware虚拟机兼容性问题处理 1、迁移过程中报错实图 2、问题原因 打开虚拟机存储的位置&#xff0c;发现文件夹下存在ctk.vmdk的文件 3、在vmware右键虚拟机编辑设置 注&#xff1a;虚拟机需要先关机 点击虚拟机选项——高级——编辑设置 将ctk.ENABLED改为…

第五套CCF信息学奥赛c++练习题 CSP-J认证初级组 中小学信奥赛入门组初赛考前模拟冲刺题(选择题)

第五套中小学信息学奥赛CSP-J考前冲刺题 1、不同类型的存储器组成了多层次结构的存储器体系,按存取速度从快到慢排列的是 A、快存/辅存/主存 B、外存/主存/辅存 C、快存/主存/辅存 D、主存/辅存/外存 答案&#xff1a;C 考点分析&#xff1a;主要考查计算机相关知识&…

在ubuntu上安装hadoop完分布式

准备工作 Xshell安装包 Xftp7安装包 虚拟机安装包 Ubuntu镜像源文件 Hadoop包 Java包 一、安装虚拟机 创建ubuntu系统 完成之后会弹出一个新的窗口 跑完之后会重启一下 按住首先用ctrlaltf3进入命令界面&#xff0c;输入root&#xff0c;密码登录管理员账号 按Esc 然后输入 …

蓝牙BLE 5.0、5.1、5.2和5.3区别

随着科技的不断发展&#xff0c;蓝牙技术也在不断进步&#xff0c;其中蓝牙BLE&#xff08;Bluetooth Low Energy&#xff09;是目前应用广泛的一种蓝牙技术&#xff0c;而BLE 5.0、5.1、5.2和5.3则是其不断升级的版本。本文将对这四个版本的区别进行详细的比较。 一、BLE 5.0…

为啥要用C艹不用C?

在很多时候&#xff0c;有人会有这样的疑问 ——为什么要用C&#xff1f;C相对于C优势是什么&#xff1f; 最近两年一直在做Linux应用&#xff0c;能明显的感受到C带来到帮助以及快感 之前&#xff0c;我在文章里面提到环形队列 C语言&#xff0c;环形队列 环形队列到底是怎么回…

FPGA高端项目:FPGA基于GS2971的SDI视频接收+纯verilog图像缩放+多路视频拼接,提供8套工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本方案的SDI接收转HDMI输出应用本方案的SDI接收图像缩放应用本方案的SDI接收HLS图像缩放HLS多路视频拼接应用本方案的SDI接收HLS动态字符叠加输出应用本方案的SDI接收HLS多路视频融合叠加应用本方案的SDI接收GTX…

【代码】Android|获取压力传感器、屏幕压感数据(大气压、原生和Processing)

首先需要分清自己需要的是大气压还是触摸压力&#xff0c;如果是大气压那么就是TYPE_PRESSURE&#xff0c;可以参考https://source.android.google.cn/docs/core/interaction/sensors/sensor-types?hlzh-cn。如果是触摸压力就是另一回事&#xff0c;我需要的是触摸压力。 不过…

【算法沉淀】刷题笔记:并查集 带权并查集+实战讲解

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《数据结构与算法&#xff1a;初学者入门指南》&#x1f4d8;&am…

Windows Server 各版本搭建文件服务器实现共享文件(03~19)

一、Windows Server 2003 打开服务器&#xff0c;点击左下角开始➡管理工具➡管理您的服务器➡添加或删除角色 点击下一步等待测试 勾选自定义配置&#xff0c;点击下一步 选择文件服务器&#xff0c;点击下一步 勾选设置默认磁盘空间&#xff0c;数据自己更改&#xff0c;最…

Onenote软件新建笔记本时报错:无法在以下位置新建笔记本

报错现象&#xff1a; 当在OneNote软件上&#xff0c;新建笔记本时&#xff1a; 然后&#xff0c;尝试重新登录微软账户&#xff0c;也不行&#xff0c;提示报错&#xff1a; 解决办法&#xff1a; 打开一个新的记事本&#xff0c;复制粘贴以下内容&#xff1a; C:\Users\Adm…

如何防御跨站请求伪造(CSRF)攻击?

CSRF 英文全称是 Cross-site request forgery&#xff0c;所以又称为“跨站请求伪造”&#xff0c;是指恶意诱导用户打开被精心构造的网站&#xff0c;在该网站中&#xff0c;利用用户的登录状态发起的跨站请求。简单来讲&#xff0c;CSRF 就是利用了用户的登录状态&#xff0c…

WordPress建站入门教程:如何在本地电脑搭建WordPress网站?

前面跟大家分享了『WordPress建站入门教程&#xff1a;如何安装本地WordPress网站运行环境&#xff1f;』&#xff0c;接下来boke112百科就继续跟大家分享本地电脑如何搭建WordPress网站。 小皮面板&#xff08;phpstudy&#xff09;的“软件管理 – 网站程序”虽然可以一键部…

excel统计分析——拉丁方设计

参考资料&#xff1a;生物统计学 拉丁方设计也是随机区组设计&#xff0c;是对随机区组设计的一种改进。它在行的方向和列的方向都可以看成区组&#xff0c;因此能实现双向误差的控制。在一般的试验设计中&#xff0c;拉丁方常被看作双区组设计&#xff0c;用于提高发现处理效应…

身份证识别系统(安卓)

设计内容与要求&#xff1a; 通过手机摄像头捕获身份证信息&#xff0c;将身份证上的姓名、性别、出生年月、身份证号码保存在数据库中。1&#xff09;所开发Apps软件至少需由3-5个以上功能性界面组成。要求&#xff1a;界面美观整洁、方便应用&#xff1b;可以使用Android原生…

徽标键锁定问题

徽标键锁定问题 1. 锁定徽标键2. 解锁徽标键 无意中发现键盘除了左右徽标键&#xff0c;其余键都正常。相关的组合键也都失效。 自己的键盘是ikbc w210款的键盘。一直使用都没有任何问题。 搜索发现使用 Fn和 徽标键组合就能锁定和解锁 徽标键。 1. 锁定徽标键 左徽标键Fn …

[项目设计] 从零实现的高并发内存池(一)

&#x1f308; 博客个人主页&#xff1a;Chris在Coding &#x1f3a5; 本文所属专栏&#xff1a;[高并发内存池] ❤️ 前置学习专栏&#xff1a;[Linux学习] ⏰ 我们仍在旅途 ​ 目录 前言 项目介绍 1.内存池 1.1 什么是内存池 池化技术 内存池 1.2 为什…

思科网络设备监控

思科是 IT 行业的先驱之一&#xff0c;提供从交换机到刀片服务器的各种设备&#xff0c;以满足中小企业和企业的各种 IT 管理需求。管理充满思科的 IT 车间涉及许多管理挑战&#xff0c;例如监控可用性和性能、管理配置更改、存档防火墙日志、排除带宽问题等等&#xff0c;这需…

区块链媒体发布推广10个热门案例解析-华媒舍

区块链技术的发展已经引起了媒体的广泛关注&#xff0c;越来越多的区块链媒体纷纷发布推广相关的热门案例。本文将介绍10个成功的区块链媒体推广案例&#xff0c;并分享它们的成功秘诀&#xff0c;帮助读者更好地了解区块链媒体推广的方法与技巧。 随着区块链技术的成熟和应用场…

常用的电阻、电容的种类和应用场合?

电阻的 a.按阻值特性:固定电阻、可调电阻、特种电阻(敏感电阻)&#xff0c;不能调节的,我们称之为固定电阻,而可以调节的,我们称之为可调电阻.常见的例如收音机音量调节的,主要应用于电压分配的,我们称之为电位器. b.按制造材料:碳膜电阻、金属膜电阻、线绕电阻&#xff0c;捷…