前言:小生不才,只懂得一些皮毛,我努力以最简单的语言将心中的想法表述出来,让更多人能够很轻松的弄明白。文章里面有不足之处望各位大牛指出,使得后面的文章能够朝着更好的方向发展。另外,大家记得点赞哟!

欢迎关注微信公众号:前端切图仔

参考文章:

天之蓝源:三分钟在GitHub上搭建个人博客​zhuanlan.zhihu.com

天之蓝源:零基础Hexo+Github搭建静态个人博客​zhuanlan.zhihu.com

天之蓝源:原生js实现点击按钮复制文本内容​zhuanlan.zhihu.com

天之蓝源:九种跨域方式实现原理​zhuanlan.zhihu.com

天之蓝源:前端面试考点多?看这些文章就够了(转载)​zhuanlan.zhihu.com

天之蓝源:干货!值得收藏的前端学习网站​zhuanlan.zhihu.com

天之蓝源:原生JS实现一个日期选择器(DatePicker)组件​zhuanlan.zhihu.com

天之蓝源:原生js一步一步实现《别踩白块儿》小游戏​zhuanlan.zhihu.com

天之蓝源:原生js利用localstorage实现简易TODO list应用​zhuanlan.zhihu.com

天之蓝源:原生js实现瀑布流效果​zhuanlan.zhihu.com

天之蓝源:原生js实现图片懒加载(lazyLoad)​zhuanlan.zhihu.com

天之蓝源:原生js实现简单路由切换​zhuanlan.zhihu.com

实现的效果:

利用本地存储实现todo 应用https://www.zhihu.com/video/1073999114060042240

一.todo list应用是什么?

可能很多小伙伴刚学完js或者其他知识的时候,不知道该怎么练习和巩固知识,然后这时候就可能会有人提出这样一个建议:写一个简单的todo list应用吧!

todo list应用其实很简单,就是一个待办事项列表应用,比如我们要做十件事,把这十件事添加到一个列表里面,然后办完一件事,我们就从列表中删除一件事,这就是一个最简单的todo list应用。接下来我们就要来实现这样一个最简单todo list应用,想要更完善的todo list应用可以自行百度学习更多知识。在本篇文章中我们利用localstorage将数据保存到本地,这样刷新浏览器数据就不会消失了。

二.什么是localstorage?

localStorage是HTML5新增的一个特性,主要是用来作为本地存储所使用的,我们都知道在之前,程序员们经常把数据存在cookie中,然后cookie的存储空间大约只有4kb,而新增的localStorage的存储容量大约有5M左右,这就解决了cookie存储容量不够的问题。但是,localStorage还是有它的优势和劣势的:

优势:

  • localStorage拓展了cookie的4K限制
  • localStorage会可以将第一次请求的数据直接存储到本地,这个相当于一个5M大小的针对于前端页面的数据库,相比于cookie可以节约带宽,但是这个却是只有在高版本的浏览器中才支持的

劣势:

  • 浏览器的大小不统一,并且在IE8以上的IE版本才支持localStorage这个属性
  • 目前所有的浏览器中都会把localStorage的值类型限定为string类型,这个在对我们日常比较常见的JSON对象类型需要一些转换
  • localStorage在浏览器的隐私模式下面是不可读取的
  • localStorage本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡
  • localStorage不能被爬虫抓取到

另外:说起了localStorage,就不得不说一下sessionStorage,sessionStorage(会话存储)和localStorage(本地存储)的区别就是localStorage属于永久性存储,而sessionStorage属于当会话结束的时候,sessionStorage中的值就会被清空。

用法:

不管是 localStorage,还是 sessionStorage,可使用的API都相同,常用的有如下几个(以localStorage为例):

  • 保存数据:localStorage.setItem(key,value);
  • 读取数据:localStorage.getItem(key);
  • 删除单个数据:localStorage.removeItem(key);
  • 删除所有数据:localStorage.clear();
  • 得到某个索引的key:localStorage.key(index);

提示: 键/值对通常以字符串存储,你可以按自己的需要转换该格式。

三.什么是事件委托?

事件委托是前端面试中的一道经典题目,事件委托还有另外一个名字,事件代理。在红皮书《JavaScript高级程序设计》里面是这样解释事件委托的:事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。官方的语言始终是比较拗口,我们通俗一点来解释:比如我们有10个DOM节点,我们需要给每一个DOM都添加一个相同事件,那么我们就需要执行for循环给每个DOM元素添加事件,那要是有100个DOM元素呢,这样一个一个的赋予事件就是很繁琐的,而且这种繁琐的操作,直接导致了页面优化的问题。因此我们就想到了另外一个方法,那就是利用JS里面的冒泡原理,至于冒泡顾名思义就是一层一层的往上冒或者一层一层的往下冒,这事件也是一样,一层一层的往上冒,一层一层的往下冒,就这样,我们只需要给一个DOM节点赋予了事件,那么所有的DOM节点都有了这个事件。

这里就简单说了一下大致原理,具体内容可以百度:事件委托面试题等等,有很多不错的解释。

四.实现思路及步骤

(一)页面结构------>HTML代码

开局一条狗,后面全靠编。我们先把页面结构搭好,这才是第一步。

<body><div class="wrapper"><h2>我是前端切图仔</h2><p></p><ul class="plates"><li>待添加事项</li></ul><form class="add-items"><input type="text" name="item" placeholder="Item Name" required><input type="submit" value="添   加"></form><div class="buttons"><button data-action="clear">删除所有</button><button data-action="check">全部选中</button><button data-action="uncheck">取消全选</button></div></div>
</body>

关于data-*属性,可以参照W3C,上面解释得挺清楚。

data-*属性设置介绍

(二)页面样式------>CSS代码

没有样式的HTML代码就是没有灵魂的,那么我们来给他添加一点灵魂吧:

html {min-height: 100vh;display: flex;justify-content: center;align-items: center;
}.wrapper {padding: 20px;max-width: 350px;background: rgba(228, 215, 215, 0.95);box-shadow: 0 0 0 5px rgba(187, 157, 157, 0.5);
}
h2 {text-align: center;margin: 0;font-weight: 200;
}
.plates {margin: 0;padding: 0;text-align: left;list-style: none;
}
.plates li {border-bottom: 1px solid rgba(0,0,0,0.2);padding: 10px 0;font-weight: 100;display: flex;
}
.plates label {flex:1;cursor: pointer;
}
.plates input {display: none;
}
.plates input + label:before {content: '⬜️';margin-right: 10px;
}
.plates input:checked + label:before {content: '☆';
}
.add-items {margin-top: 20px;
}
.add-items input {padding:10px;outline:0;border:1px solid rgba(0,0,0,0.1);
}
.add-items input:nth-child(1){width: 61.3%;
}
.add-items input:nth-child(2) {width: 30%;color: rgb(85, 108, 128);font-weight: 700;
}
.buttons button {width: 100px;margin-top: 10px;height: 40px;color: rgb(85, 108, 128);font-weight: 700;border:1px solid rgba(0,0,0,0.1);
}

添加CSS样式后的页面

(三)页面逻辑------>JS代码

下面是最重要的js代码了,js代码负责我们的逻辑部分,是整个demo的核心,只要大家跟着注释解析代码很容易理解。

(function(){function newFun() {var addItems = document.querySelector('.add-items');//选中类为.add-items的元素var itemsList = document.querySelector('.plates');//todolist列表var buttons = document.querySelector('.buttons');var items = JSON.parse(localStorage.getItem('items')) || [];//获取本地缓存到的所有item,将一个对象字符串转换为对象//添加item方法function handleSubmit(e) {e.preventDefault();//阻止默认事件的触发,防止在提交后页面自己刷新var name = this.querySelector('[name=item]').value;//获取输入框中的值var item = {name: name,done: false//增加一个状态bool,后面会用到};items.push(item);localStorage.setItem('items', JSON.stringify(items));//将对象转化为字符串,因为本地存储只能以字符串的形式存储updateList( items, itemsList);//更新列表this.reset();}function updateList(plates = [], plateList) {plateList.innerHTML = plates.map( function(plate, i)  {return '<li><input type="checkbox" data-index="' + i + '" id="plate' + i + '" ' + (plate.done ? 'checked' : '') + ' /><label for="plate' + i + '">' + plate.name + '</label></li>';}).join('');}//事件委托// 此处使用到了事件委托:// 假设我们队一个input列表进行了事件监听,但我们如法保证,此列表在接下来的状态下是否进行了更新,刷新等改变原来节点的操作,如果有这样的操作出现,那么我们之前的事件监听器就无法再起到监听的作用;// 但我们可以对input列表的父元素进行事件监听,让它们的父元素处于监听状态,当我们所点击的元素是其子元素的话,就告诉它的子元素,执行相应的事件;// 相当于委托父元素帮我们监听所有子元素,这样无论子元素列表进行怎么样的更新,改变,只要父元素节点不发生改变就可以持续起到监听的 作用。// 通过e.target.matches('input')可以判断所点击的元素是不是input元素,e.target返回所点击的宿主元素。// 通过获取到所点击的列表的序号,更改其done属性,更新后进行存储,就可以实现完成状态的事件。function toggleChecked(e) {if (!e.target.matches('input')) return;var item = e.target.dataset.index;items[item].done = !items[item].done;localStorage.setItem('items', JSON.stringify(items));updateList( items, itemsList);}//添加button事件function doButtonPress(e) {var action = e.target.dataset.action;switch (action) {case "clear":items = [];break;case "check":items.map( function(item) {return item.done = true;} );break;case "uncheck":items.map( function(item) {return item.done = false ;} );break;default:return;}localStorage.setItem('items', JSON.stringify(items));updateList( items, itemsList);}addItems.addEventListener('submit', handleSubmit);itemsList.addEventListener('click', toggleChecked);buttons.addEventListener('click', doButtonPress);updateList(items, itemsList);}document.addEventListener('DOMContentLoaded', newFun);//当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完成加载。另一个不同的事件 load 应该仅用于检测一个完全加载的页面。 在使用 DOMContentLoaded 更加合适的情况下使用 load 是一个令人难以置信的流行的错误,所以要谨慎。//注意:DOMContentLoaded 事件必须等待其所属script之前的样式表加载解析完成才会触发。}());

(四)所有代码

五.总结

本次这个demo的核心就是localstorage(本地存储)的使用以及事件委托的理解,笔者也是在边写代码边理解,参照网上一些大牛的代码,遇到不懂的就上网百度,慢慢来实现。我们可以回顾一下我们是怎么做的:

  • 首先,一进入页面就添加事件DOMContentLoaded ,执行函数newFun
  • 然后就是获取dom元素和本地存储的元素
  • 然后有三个方法,分别是添加item元素,监听input列表方法,和点击button所执行的方法
  • 执行相应的函数

总的来说,虽然流程是比较清楚的,但是代码的细节还是需要仔细斟酌。

六.补充

在浏览器退出的时候可以清除一下缓存,因为这毕竟是我们的demo,没那么正式:

 window.onbeforeunload = function (e) {localStorage.removeItem('items');e.returnValue = confirmationMessage; // Gecko, Trident, Chrome 34+
};
window.onbeforeunload = function (event) {var message = 'Important: Please click on 'Save' button to leave this page.';if (typeof event == 'undefined') {event = window.event;}if (event) {event.returnValue = message;}return message;
};

七.源代码

更多源代码请移步GitHub

Hacker233/JavaScript​github.com

js事件里面套事件怎么不管用_原生js利用localstorage实现简易TODO list应用相关推荐

  1. 根据id删除localstorage数据_原生js利用localstorage实现简易TODO list应用

    前言:小生不才,只懂得一些皮毛,我努力以最简单的语言将心中的想法表述出来,让更多人能够很轻松的弄明白.文章里面有不足之处望各位大牛指出,使得后面的文章能够朝着更好的方向发展.另外,大家记得点赞哟! 欢 ...

  2. 如何更改html广告,js 动态改变广告代码DIV的位置_原生JS通过innerHTML改变div位置...

    在实际的广告应用中时不时会出现这个需求,就是我投放的广告位距离用户经常点击的翻页太远了,网站主不愿意为了这个需求去把整站的内容生成一遍,那会耗费很长时间,而且不确定有没有错误,这个时候就需要广告代码中 ...

  3. js 控制鼠标_原生js实现改变视频播放速率

    前言:前几天考研成绩刚刚出来,有人欢喜有人悲,不管结果怎么样,只要努力过,就不存在遗憾一说.大家都知道考研复习的时候会有大量的时间用来看教学视频,就比如说"张宇高数"等等.考研复习 ...

  4. java循环购物车结算系统_原生JS实现购物车结算功能代码

    html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD ...

  5. java使用重绘实现拖动_原生JS使用Canvas实现拖拽式绘图功能

    一.实现的功能 1.基于oop思想构建,支持坐标点.线条(由坐标点组成,包含方向).多边形(由多个坐标点组成).圆形(包含圆心坐标点和半径)等实体 2.原生JavaScript实现,不依赖任何第三方j ...

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

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

  7. js 取得input绑定的datalist中的值_原生JS写一个ToDo Demo

    周六加班没什么事,于是乎...上班摸鱼,用原生JS写了一个ToDo Demo,废话少叙,直接看效果: 如图,实现了以下需求(以下的具体实现我会一一道来): 0.页面的基本布局: 1.rem布局.在不同 ...

  8. 单机按钮来图片轮播_原生js如何实现轮播图效果?

    第一种: 这个是之前写的,比较草率,没有注释,如果这个看不懂就去看第二个,比较仔细,主要是了解他,后面都会有一些插件来使用,很方便,只要几行代码就可写出各种各样的代码,所以,不懂的话,不要太在意, 第 ...

  9. 微信通讯录java实现_原生JS实现微信通讯录

    最近工作当中再一次遇到要实现一个车辆列表,要求能够像微信通讯录一样,实现右侧滑动,点击功能,并且滑动过程中,能够有提示.原来用jquery实现过一次,为了精简代码,现在用原生的实现一次.想必工作中大家 ...

最新文章

  1. joc杂志影响因子2019_2019年放射学领域SCI主要杂志影响因子汇总
  2. 在T-SQL语句中访问远程数据库(openrowset/opendatasource/openquery)
  3. 如何解决make: Nothing to be done for `all‘ 的方法
  4. oracle存储过程、声明变量、for循环(转)
  5. python cx_oracle_Python3安装cx_Oracle连接oracle数据库实操总结
  6. 鸟哥的Linux私房菜(基础篇)- 鸟哥的第一本书的主要内容,以 Mandrake 9.0 为例
  7. ef 排序string转int_Java排序算法——基数排序(Radix Sort)
  8. CS144 lab0 笔记
  9. python url拼接_python学习笔记——urllib篇
  10. 格式 数组的基本使用 0912
  11. 在 Windows 10 的 Linux 子系统(WSL)中运行 Kali
  12. javascript 数组所有方法
  13. AccessControl专业智能门禁管理系统 操作说明书
  14. 远景html制造机模板,台式机ALC892制作仿冒appleHDA的教程,前置MIC自动检测。
  15. 中国工商银行上海市分行-存量房交易服务平台
  16. app中使用企业微信sdk分享小程序报错:小程序路径错误,加载超时 解决办法。
  17. 怎样利用开源软件赚钱?
  18. C语言程序设计教程 北京邮电,C语言程序设计教程(第3版)/ 杨路明 9787563543403 北京邮电...
  19. 本体李俊|区块链的实际业务场景需要哪些技术模块?
  20. 瑞星 HookCont.sys <= 24.0.0.5 驱动本地拒绝服务漏洞

热门文章

  1. 二进制数据结构:JavaScript中的树和堆简介
  2. 网站加载速度 优化_您肯定要优化网站的加载速度。 这是如何做。
  3. 为知笔记 Markdown 新手指南
  4. 雨滴桌面时间插件_只需要五步,让你的桌面变得干净漂亮
  5. Python打印A~Z的26个字母,你会怎样打印?
  6. 进程的创建-Process子类(python 版)
  7. Tensorflow CNN(两层卷积+全连接+softmax)
  8. 机器学习两大派别--南大周志华
  9. Asp.net三层结构原理与用意学习入门教程(一)
  10. ASP.Net请求处理模式