周六加班没什么事,于是乎。。。上班摸鱼,用原生JS写了一个ToDo Demo,废话少叙,直接看效果:

如图,实现了以下需求(以下的具体实现我会一一道来):

0.页面的基本布局;

1.rem布局。在不同移动端模拟器下,布局也不会乱,实现了响应式布局;

2.在输入框内敲击回车键,添加代办事项;

3.待办事项<===>完成事项之间的转化;

4.删除待办事项 / 完成事项;

5.本地数据存储;

===================================================

于我来说,这个小demo,我最大的收获就是知道“事件委托”如何使用,以前仅仅停留在概念层,现在对其应用层也算是有了一定的理解。以前处理需要循环遍历的元素,例如每个li元素需要绑定点击事件,可能我的第一反应就是给每个li都绑定一个点击事件,这样写往往会导致代码臃肿,而且影响性能,毕竟每个元素都需要绑定一个点击事件。如果有需求要为一万个li绑定点击事件,那该怎么办?

这时候通过事件委托就可以很好地解决这个问题的,只需要在的父元素上绑定事件,然后通过event事件对象来确定具体的触发子元素即可,非常好用方便。

如果还不是很懂事件委托的朋友可以看看下面这篇Blog,相信看完后一定对你有很大的帮助。

js中的事件委托(事件代理)详解 - lauzhishuai - 博客园​www.cnblogs.com

好了,现在来说说具体是怎么实现的:

0.页面布局

这个其实没什么好说的了,flex布局用的比较多。最需要提一下的就是完成事项灰色效果的实现了:

/* 修改所有图片的颜色为黑白 (100% 灰度) */
-webkit-filter: grayscale(100%);
/* Chrome, Safari, Opera */filter: grayscale(100%);

PS:源码我贴在文章的末尾,有需要的可以自行下载~

1.rem布局

我的Blog里面有讲,直通车------->

https://zhipengyang0605.github.io/%E5%93%8D%E5%BA%94%E5%BC%8F%E5%B8%83%E5%B1%80/2020/07/19/%E7%A7%BB%E5%8A%A8%E7%AB%AF%E9%A1%B9%E7%9B%AE%E4%B8%AD%E4%BD%BF%E7%94%A8rem/#​zhipengyang0605.github.io

demo 里面我就简单的写了这几行代码~封装成rem.js文件了

function resize () {// 1rem = 100pxvar designWidth = 750 // 设计稿的宽度var rootFontSize = 100 // 将html root的font-size设置为100pxdocument.documentElement.style.fontSize = rootFontSize + 'px'var width = document.documentElement.clientWidth // 屏幕尺寸var fontSize;fontSize = (width / designWidth) * rootFontSize // 模拟器上的实际字体大小
}window.onresize = resize // 屏幕尺寸大小变化时触发
document.addEventListener('DOMContentLoaded', resize, false) // 当浏览器解析完文档触发该事件

这里我默认以iPhone6 为标准,设计稿的宽度为750px,设置网页根元素的font-size等于100px,iPhone6模拟器的宽高为375x667,因此根据这个公式

fontSize =(width / designWidth)* rootFontSize

不难得出1rem = 100px了,因此接下来的所有布局都只是用rem不再使用px。

2.在输入框内敲击回车键,添加代办事项

主要通过监听keydown事件,然后通过事件对象e的key属性的值是否为‘Enter’,若为Enter则执行render函数,render函数的作用是将数据渲染到页面上。这里的数据为dataList,初始化为空数组,每当敲击回车键后将自定义的对象push到该数组中去。定义的对象结构为:

var obj = {isChecked: false, // checkbox的状态是否选中content: value, // input的输入内容isDone: false // 是否完成}

以下是实现的主要代码:

    // 鼠标按下事件input.addEventListener('keydown', handleInput)// input事件function handleInput (e) {if (e.key === 'Enter') { // 敲回车执行事件var value = e.target.valuevar obj = {isChecked: false,content: value,isDone: false}dataList.push(obj)// 将数据存储到本地localStorage.setItem('toDoList', JSON.stringify(dataList));// 在这里渲染render()// 输入完毕后清除输入框的内容e.target.value = ''}}// 处理渲染页面函数function render () {// 渲染之前清空内容doingbox.innerHTML = ''donebox.innerHTML = ''// 判断是doing渲染还是done渲染dataList.forEach(function (item, index) {if (!item.isChecked) {// 创建一个元素var li = document.createElement('li')li.innerHTML = `<div class="item-left"><input type="checkbox" class="checkbox" data-index = "${index}"><span>${item.content}</span></div><button class="del" data-index = "${index}">删除</button>`// 插入一个元素doingbox.appendChild(li)li.className = 'doing-item'} else {// 创建一个元素var li = document.createElement('li')li.innerHTML = `<div class="item-left"><input type="checkbox" class="checkbox" checked="${item.isChecked}" data-index = "${index}"><span>${item.content}</span></div><button class="del" data-index = "${index}">删除</button>`// 插入一个元素donebox.appendChild(li)li.className = 'done-item'}})}

render函数这里有几点要特别注意:

(1).每次插入之前需要把上一次的innerHTML清空,不然会重复渲染;

(2).需要绑定data-index,方便后续删除/事项切换获取下标;

3.待办事项<===>完成事项之间的转化

思路主要是监听checkbox的change事件,通过改变checkbox的checked属性,重新设置dataList中每一项中isChecked和isDone这两个属性,然后重新调用render函数(只要dataList被操作了就需要重新调用render函数)

    // checkbox改变触发todobox.addEventListener('change', handleChangeEvent)// 处理change事件function handleChangeEvent (e) {var currentindex = e.target.dataset.indexdataList[currentindex].isChecked = 'checked'// render()dataList[currentindex].isDone = !dataList[currentindex].isDoneif (dataList[currentindex].isDone) { //已完成render()} else { // 未完成dataList[currentindex].isDone = false// 去除checked状态dataList[currentindex].isChecked = falserender()}// 将数据存储到本地localStorage.setItem('toDoList', JSON.stringify(dataList));}

4.删除待办事项 / 完成事项

要实现删除功能其实很简单,为每个todo/done元素绑定click事件,点击获取对应的index,然后再todoList中删除该项,然后重新调用render函数即可。绑定事件可以不用手动为每个li绑定事件,可以使用事件委托,为整个页面的某个dox绑定点击事件,结合事件对象e.target.nodeName,精确点击的元素即可。

    // 点击事件todobox.addEventListener('click', handleDel)// 处理删除功能function handleDel (e) {// 只有当元素为button时才执行删除操作if (e.target.nodeName.toLowerCase() === 'button') {// 删除提示var result = window.confirm('删除要三思啊~~~')if (result) {// 获取要删除元素的下标var activeIndex = e.target.dataset.index// 删除对应元素dataList.splice(activeIndex, 1)// 重新将数组保存到本地localStorage.setItem('toDoList', JSON.stringify(dataList));// 重新渲染页面render()}}}

我这里使用了window.confirm来提示是否删除,接受一个返回值,当点击确定的时候会返回true,反之为false。

5.本地数据存储

本地数据存储HTML5提供了一个新的API:localStorage,它可以实现将数据保存到浏览器本地,并且没有时间限制,除非手动删除。

有不明白的小伙伴可以看看菜鸟教程,简单易懂;

Window localStorage 属性​www.runoob.com

使用本地存储的时候也需要注意几点:

(1)只要dataList发生改变就需要将数据重新存储;

(2)localStorage 只能保存字符串,如果直接setItem 一个对象,则会执行Object 的toString() 方法,保存其结果,你可能会得到“[object Object]”的结果。由于dataList的子项均为对象,因此可以借助JSON.stringify()方法将dataList转为一个字符串。同时还要注意,localStorage.getItem()得到的是一个字符串,需要借助JSON.parse()将其转为对象。

最后附上我的源码,需要的朋友可以去我的github上clone~

https://github.com/ZhipengYang0605/todo-demo​github.com

js 取得input绑定的datalist中的值_原生JS写一个ToDo Demo相关推荐

  1. js 取得input绑定的datalist中的值_javascript基础修炼(9)——MVVM中双向数据绑定的基本原理...

    [小宅按] 开发者的javascript造诣取决于对[动态]和[异步]这两个词的理解水平. 一. 概述 1.1 MVVM模型 MVVM模型是前端单页面应用中非常重要的模型之一,也是Single Pag ...

  2. js实现随机选取[10,100)中的10个整数,存入一个数组,并排序。 另考虑(10,100]和[10,100]两种情况。...

    1.js实现随机选取[10,100)中的10个整数,存入一个数组,并排序. 1 <!DOCTYPE html> 2 <html lang="en"> 3 & ...

  3. history.go(-1)返回页面后,此页面中的input标签隐藏域中的值消失

    问题描述:通过javascript:history.go(-1)返回页面后input标签隐藏域中的值消失 解方法:将 <input type="hidden" value=& ...

  4. vue如何使用原生js写动画效果_原生js写一个无缝轮播图插件(支持vue)

    轮播图插件(Broadcast.js) 前言:写这个插件的原因 前段时间准备用vue加上网易云的nodejs接口,模拟网易云音乐移动端.因为想自己写一遍所有的代码以及加固自己的flex布局,所以没有使 ...

  5. 服务器lIS绑定网站,DataList 中动态绑定服务器子控件的代码

    DataList 中动态绑定服务器子控件的代码 更新时间:2007年09月10日 21:54:04   作者: 1.首先绑定dbList (一个DataList控件名称) 2.设置绑定子控件需要的关键 ...

  6. html 监听input输入框的值,利用原生JS实时监听input框输入值

    利用原生JS实时监听input框输入值 原生JS中可以使用oninput,onpropertychange,onchange oninput,onpropertychange,onchange的用法 ...

  7. js获取request中的值_基于node.js的开发框架 — Koa

    一.简介 Koa 基于nodeJs平台的下一代web开发框架,由 Express 幕后的原班人马打造,致力于成为一个更小.更富有表现力.更健壮的 Web 框架.使用 koa 编写 web 应用,通过组 ...

  8. js取iframe 上级页面_原生js获取iframe中dom元素--父子页面相互获取对方dom元素的方法...

    用原生js在父页面获取iframe子页面的元素,以及在子页面获取父页面元素,这是平时经常会用到的方法,这里写一个例子来总结下: 1.父页面(demo.html),在父页面修改子页面div的背景色为灰色 ...

  9. html读取model的值,Js和Thymeleaf如何获取model中的值

    简述 在大多数的项目架构中,使用SPringBoot发布微服务,前端采用Thymeleaf做为Html模版,使用Jquery做为动态脚本,那么Thymeleaf和Jquery是如何获取Model中的数 ...

最新文章

  1. sersync 同步
  2. DataWorks搬站方案:Azkaban作业迁移至DataWorks
  3. linux 星号 通配符,如何在bash中转义通配符/星号字符?
  4. 【C语言】第六章 集合数据与数组 题解
  5. linux中断调用spi函数,基于Linux的ARM与FPGA SPI驱动,中断函数调用spidev_sync_read(),出现异常...
  6. python join_Python中join()方法的用法
  7. iPhone企业应用实例分析之一:系统介绍和需求及主要用例
  8. 使用sshfs挂载服务器文件系统,用curlftpfs挂载FTP服务器
  9. 基于51单片机的循迹小车
  10. linux go语言运行环境,linux下怎么安装go语言环境
  11. “人生就像滚雪球,重要的是发现很湿的雪和很长的坡。”+复利的力量
  12. 审车的时候环保怎样安全通过_审车环保3次不过怎么办,年检尾气不合格怎么办...
  13. 网易云音乐评论 破解JS加密参数
  14. php怎么显示不了图片,php显示不了图片的解决办法,
  15. Unity流水账9:Timeline
  16. 计算机视觉 目标分割
  17. 〖Python自动化办公篇④〗- 文件自动化管理 - 文件查找与基于文件内容查找文件
  18. 中国地质大学(武汉)计算机考研资料汇总
  19. xxl-job 定时任务简单使用
  20. EarlyStopping技术

热门文章

  1. OCP学习和培训ppt汇总
  2. C#处理鼠标和键盘事件
  3. 建立高可用性的数据库群集
  4. Python3 异常: name ‘basestring‘ is not defined
  5. 【白皮书下载】2020年数字营销与商业增长白皮书.pdf
  6. 【干货】2020年陆奇最新万字演讲:世界新格局下的创业创新机会.pdf(附下载链接)...
  7. 【报告分享】2020-2021跨境出口电商增长白皮书.pdf(附下载链接)
  8. 离开小厂进大厂的第一周:我“后悔”了
  9. PyTorch 深度学习:32分钟快速入门——ResNet
  10. java 遍历所有内部类_JAVA-内部类