jQuery模仿ToDoList实现简单的待办事项列表
功能:在文本框中输入待办事项按下回车后,事项会出现在未完成列表中;点击未完成事项前边的复选框后,该事项会出现在已完成列表中,反之亦然;点击删除按钮会删除该事项;双击事项可以修改事项的内容。待办事项的数据是保存到本地存储的(localStorage),就算关闭页面再打开,数据还是存在的(前提是要用相同浏览器)。
ToDoList链接:ToDoList—最简单的待办事项列表
先把css样式以及js文件引入进来,jQuery文件要写在你自己的js文件上边
<link rel="stylesheet" href="css/index.css">
<script src="js/jquery.min.js"></script>
<script src="js/todolist.js"></script>
HTML代码:
<body>
<header>
<section>
<label for="title">ToDoList</label>
<input type="text" id="title" name="title" placeholder="添加ToDo" required="required" autocomplete="off" />
</section>
</header>
<section>
<h2>正在进行 <span id="todocount"></span></h2>
<ol id="todolist" class="demo-box"> </ol>
<h2>已经完成 <span id="donecount"></span></h2>
<ul id="donelist"> </ul>
</section>
<footer>
Copyright © 2019
</footer>
</body>
body {
margin:;
padding:;
font-size: 16px;
background: #CDCDCD;
} header {
height: 50px;
background: #333;
background: rgba(47, 47, 47, 0.98);
} section {
margin: 0 auto;
} label {
float: left;
width: 100px;
line-height: 50px;
color: #DDD;
font-size: 24px;
cursor: pointer;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
} header input {
float: right;
width: 60%;
height: 24px;
margin-top: 12px;
text-indent: 10px;
border-radius: 5px;
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.24), 0 1px 6px rgba(0, 0, 0, 0.45) inset;
border: none
} input:focus {
outline-width: 0
} h2 {
position: relative;
} span {
position: absolute;
top: 2px;
right: 5px;
display: inline-block;
padding: 0 5px;
height: 20px;
border-radius: 20px;
background: #E6E6FA;
line-height: 22px;
text-align: center;
color: #666;
font-size: 14px;
} ol,
ul {
padding:;
list-style: none;
} li input {
position: absolute;
top: 2px;
left: 10px;
width: 22px;
height: 22px;
cursor: pointer;
} p {
margin:;
} li p input {
top: 3px;
left: 40px;
width: 70%;
height: 20px;
line-height: 14px;
text-indent: 5px;
font-size: 14px;
} li {
height: 32px;
line-height: 32px;
background: #fff;
position: relative;
margin-bottom: 10px;
padding: 0 45px;
border-radius: 3px;
border-left: 5px solid #629A9C;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07);
} ol li {
cursor: move;
} ul li {
border-left: 5px solid #999;
opacity: 0.5;
} li a {
position: absolute;
top: 2px;
right: 5px;
display: inline-block;
width: 14px;
height: 12px;
border-radius: 14px;
border: 6px double #FFF;
background: #CCC;
line-height: 14px;
text-align: center;
color: #FFF;
font-weight: bold;
font-size: 14px;
cursor: pointer;
} footer {
color: #666;
font-size: 14px;
text-align: center;
} footer a {
color: #666;
text-decoration: none;
color: #999;
} @media screen and (max-device-width: 620px) {
section {
width: 96%;
padding: 0 2%;
}
} @media screen and (min-width: 620px) {
section {
width: 600px;
padding: 0 10px;
}
}
index.css
接下来开始写我们自己的js代码
将多次使用的代码封装成函数,方便使用
①获取本地存储的数据。如果本地有数据则直接获取过来,没有数据的话就返回一个空数组
function getDate() {
var data = localStorage.getItem("todolist"); // 将获取到的数据赋给data
if(data !== null) { // 如果本地有数据,则返回数据
return JSON.parse(data); // 本地存储只能存储字符串,所以要想获取里边的数据就必须将字符串转换为数组形式返回
} else {
return []; // 如果本地没有数据,则返回一个空数组
}
}
②保存本地存储数据
function saveDate(data) {
// 用JSON.stringify()将数组转化成字符串保存到本地存储
localStorage.setItem("todolist", JSON.stringify(data));
}
③渲染页面 加载数据
先将本地存储数据获取过来;将他们遍历(遍历之前先将列表清空),看他们是否已经被完成(通过数组里我们自己添加的done的值为true还是false来判断),如果已经被完成则添加到ul列表,否则添加进ol列表里;同时声明两个变量来保存已完成和未完成事项的个数
function load() {
var data = getDate(); // 先获取本地存储数据 // 遍历本地存储数据 将他们添加到列表中
$("ol, ul").empty(); // 遍历之前先清空列表
var doneCount = 0; // 已经完成的个数
var todoCount = 0; // 正在进行的个数
$.each(data, function(i, ele) { // i为索引 ele为遍历对象
// 如果复选框被选中(已完成done: true)添加到ul里,未被选中(未完成done: false)添加到ol里
if(ele.done) {
$("ul").prepend("<li><input type='checkbox' checked='checked' > <p>" + ele.title + "</p> <a href='javascript:;' index=" + i + "></a></li>");
doneCount++; // 每添加一个li,已完成数加一
} else {
$("ol").prepend("<li><input type='checkbox'> <p>" + ele.title + "</p> <a href='javascript:;' index=" + i + "></a></li>");
todoCount++;
}
})
$("#donecount").text(doneCount);
$("#todocount").text(todoCount);
}
1. 用户输入待办事项按下回车,将事项添加进列表
给文本框绑定键盘按下事件,通过ASCII值来判断用户是否按下了回车(回车的ASCII值为13);
不能直接在本地存储里更改数据,所以要先获取数据(数组形式),把数组进行更新数据(把最新数据追加给数组),再保存到本地存储;
然后对页面进行重新渲染 更新数据
load(); // 第一步先渲染页面,不然一开始刷新页面时列表不显示
$("#title").on("keydown", function(event) {
if(event.keyCode === 13) {
if($(this).val().trim() !== "") { // trim()去除字符串两侧空格
var data = getDate(); // 获取本地存储数据
// 把数组进行更新数据,把最新数据追加给数组
data.push({title: $(this).val(), done: false});
saveDate(data); // 保存到本地存储
load(); // 渲染加载到页面
$(this).val("");
}
}
})
2. 删除待办事项
先获取本地存储数据;
用attr获取自定义属性index(索引)得到用户点击的第几个事项,通过索引删除数组里对应的那组数据;
将更新过的数组保存到本地存储 再渲染给页面
$("ol, ul").on("click", "a", function() {
var data = getDate(); // 获取本地数据(data是局部变量,不用担心冲突)
var index = $(this).attr("index"); // 用attr获取自定义属性index,得到索引
// splice(index, num)删除数组对象 index为开始删除的位置,num为删除几个
data.splice(index, 1);
saveDate(data);
load();
})
3. 用户点击复选框来选择事项已完成或未完成
获取本地存储数据;
通过复选框的兄弟a的index属性来获取用户点击的事项的索引(index),将第index个数据的done属性值修改为复选框的值;
将更新过的数组保存到本地存储 再渲染给页面
$("ol, ul").on("click", "input", function() {
var data = getDate();
// 利用a获取用户点击的第几个复选框
var index = $(this).siblings("a").attr("index");
// 修改数据:data[索引].属性名 获取固有属性用prop
data[index].done = $(this).prop("checked");
saveDate(data);
load();
})
4. 用户可以通过双击事项进行修改
获取本地存储数据;通过a获取索引index;
在p里创建一个文本框,把p原来的内容赋给文本框,并让其为选中状态;
当文本框失去焦点或用户点击回车,将修改后的内容给当前数组对象的title属性;
将更新过的数组保存到本地存储 再渲染给页面
$("ol, ul").on("dblclick", "p", function() {
var data = getDate();
var index = $(this).siblings("a").attr("index");
// 先将p原来的内容获取过来
var str = $(this).text();
// 创建一个文本框,直接添加到p里
$(this).prepend('<input type="text" />');
// 将原来内容给文本框,并让其为选中(select)状态
var input = $(this).children();
input.val(str);
input.select();
// 当文本框失去焦点,将修改过的文本框的内容给title
$(input).on("blur", function() {
data[index].title = input.val();
saveDate(data);
load();
})
// 按下回车时保存修改
$(input).on("keyup", function(e) {
if(e.keyCode === 13) { // 回车ASCII值为13
// 手动调用点击事件
this.blur();
}
})
})
详细JS代码:
$(function() {
load(); // 第一步先渲染页面,不然一开始刷新页面时列表不显示
// 1、给文本框绑定键盘按下事件
$("#title").on("keydown", function(event) {
if(event.keyCode === 13) {
if($(this).val().trim() !== "") { // trim()去除字符串两侧空格
var data = getDate(); // 获取本地存储数据
// 把数组进行更新数据,把最新数据追加给数组
data.push({title: $(this).val(), done: false});
saveDate(data); // 保存到本地存储
load(); // 渲染加载到页面
$(this).val("");
}
}
})
//2、删除待办事项
$("ol, ul").on("click", "a", function() {
var data = getDate(); // 获取本地数据(data是局部变量,不用担心冲突)
var index = $(this).attr("index"); // 用attr获取自定义属性index,得到索引
// splice(index, num)删除数组对象 index为开始删除的位置,num为删除几个
data.splice(index, 1);
saveDate(data);
load();
})
//3、正在进行和已完成
$("ol, ul").on("click", "input", function() {
var data = getDate();
// 利用a获取用户点击的第几个复选框
var index = $(this).siblings("a").attr("index");
// 修改数据:data[索引].属性名 获取固有属性用prop
data[index].done = $(this).prop("checked");
saveDate(data);
load();
})
// 4、修改事项
$("ol, ul").on("dblclick", "p", function() {
var data = getDate();
var index = $(this).siblings("a").attr("index");
// 先将p原来的内容获取过来
var str = $(this).text();
// 创建一个文本框,直接添加到p里
$(this).prepend('<input type="text" />');
// 将原来内容给文本框,并让其为选中(select)状态
var input = $(this).children();
input.val(str);
input.select();
// 当文本框失去焦点,将修改过的文本框的内容给title
$(input).on("blur", function() {
data[index].title = input.val();
saveDate(data);
load();
})
// 按下回车也可以保存修改
$(input).on("keyup", function(e) {
if(e.keyCode === 13) { // 回车ASCII值为13
// 手动调用点击事件
this.blur();
}
})
})
// 获取本地存储数据
function getDate() {
var data = localStorage.getItem("todolist"); // 将获取到的数据赋给data
if(data !== null) { // 如果本地有数据,则返回数据
return JSON.parse(data); // 本地存储只能存储字符串,所以要获取里边的数据就必须将字符串转换为数组形式返回
} else {
return []; // 如果本地没有数据,则返回一个空数组
}
}
// 保存本地存储数据
function saveDate(data) {
// 用JSON.stringify()将数组转化成字符串保存到本地存储
localStorage.setItem("todolist", JSON.stringify(data));
}
// 渲染加载数据
function load() {
var data = getDate(); // 先获取本地存储数据 // 遍历本地存储数据 将他们添加到列表中
$("ol, ul").empty(); // 遍历之前先清空列表
var doneCount = 0; // 已经完成的个数
var todoCount = 0; // 正在进行的个数
$.each(data, function(i, ele) { // i为索引 ele为遍历对象
// 如果复选框被选中(已完成done: true)添加到ul里,未被选中(未完成done: false)添加到ol里
if(ele.done) {
$("ul").prepend("<li><input type='checkbox' checked='checked' > <p>" + ele.title + "</p> <a href='javascript:;' index=" + i + "></a></li>");
doneCount++; // 每添加一个li,已完成数加一
} else {
$("ol").prepend("<li><input type='checkbox'> <p>" + ele.title + "</p> <a href='javascript:;' index=" + i + "></a></li>");
todoCount++;
}
})
$("#donecount").text(doneCount);
$("#todocount").text(todoCount);
}
})
jQuery模仿ToDoList实现简单的待办事项列表的更多相关文章
- Go For It ,一个灵活的待办事项列表程序
导读 Go For It,是我们开源工具系列中的第十个工具,它将使你在 2019 年更高效,它在 Todo.txt 系统的基础上构建,以帮助你完成更多工作. 每年年初似乎都有疯狂的冲动想提高工作效率. ...
- 使用vue实现简单的待办事项
待办事项 效果图 目录结构 详细代码 AddNew.vue <template> <div> <input v-model="content"/> ...
- Javascript之网页版待办事项
本文使用原生JS实现站点 http://www.todolist.cn/ 的基本功能. 其中页面的HTML布局和CSS样式取用原站,JS部分为自己编写. 效果图 完整代码 HTML.JS部分 < ...
- 模仿ToDoList
1.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...
- js仿toDoList(待办事项)练习
JS的一个小练习 展示成果 话不多说 html骨架 <!DOCTYPE html> <html lang="en"> <head> <me ...
- todolist待办事项
使用html/css原生js实现待办事项列表: 支持添加待办事项,删除待办事项,切换待办事项的状态(正在进行,已经完成) 支持对正在进行以及已经完成事项编辑(单击内容即可编辑) 源代码:链接:http ...
- 个人待办事项工具的设计和搭建(IFE前端2015春季 任务3)
这是我几个月之前的项目作品,花了相当的时间去完善.博客人气不高,但拿代码的人不少,所以一直处于保密状态.没有公开代码.但如果对你有帮助,并能提出指导意见的,我将十分感谢. IFE前端2015春季 任务 ...
- 青否云 - 小程序待办事项 jquery开源系统
青否云最新开源系统:小程序待办事项 jquery-demo 青否云 Jquery demo 下载地址:https://github.com/qingful/jquery-demo 官网 http:// ...
- 青否云 - 小程序待办事项vue开源系统
青否云最新开源系统:小程序待办事项 vue-demo 青否云 vue demo 下载地址:https://github.com/qingful/vue-demo 官网 http://cloud.qin ...
随机推荐
- 为什么 Redis 是单线程的?
以前一直有个误区,以为:高性能服务器 一定是 多线程来实现的 原因很简单因为误区二导致的:多线程 一定比 单线程 效率高.其实不然. 在说这个事前希望大家都能对 CPU . 内存 . 硬盘的速度都有了 ...
- 记一次net/net core delete 方法报404 解决方案
今天一个net core的delete方法 执行的时候 报404 网上查阅资料后发现是IIS 默认只允许get/post方法接入 网上查找资料后 在web.config添加如下代码: 意为移除WebD ...
- Selenium+Java(五)iframe/frame多表单处理
前言 如果网页中使用了frame,则在使用Selenium定位元素时需要切换到对应的frame,否则会定位不到需要的元素. 切换到需要切换的frame中 driver.switchTo().frame ...
- myql数据库,sql横排转竖排以及竖排转横排,oracle的over函数的使用
一.引言 前些日子遇到了一个sql语句的横排转竖排以及竖排转横排的问题,现在该总结一下,具体问题如下: 这里的第二题和第三题和下面所讲述的学生的成绩表是相同的,这里给大家留一下一个念想,大家可以自己做 ...
- sudo控制用户对系统命令的使用权限
sudo控制用户对系统命令的使用权限 sudo相关概念 普通用户涉及到超级权限的运用,管理员如果想让该普通用户通过su来切换到root获得超级权限,就必须把root权限密码告诉用户.但是如果普通用户有 ...
- MySQL主从扩展知识
6月29/7月2日任务 说明:这两天无新课,主要是扩充知识面注意:这两天的任务,需要回专贴.需要你们通过看这些东西总结成自己的心得. 不能照搬,必须要自己理解,能看多少就看多少,看不完也没有关系,但一 ...
- 怎么解决js中如滑动到最底端一次操作触发多次
定义一个布尔类型到标志,处理中将起设置为true ,处理完改完false,逻辑: data{ isInProcessing:false } //逻辑函数过程中: if(isInProcessing){ ...
- 【Python成长之路】装逼的一行代码:快速共享文件【华为云分享】
[写在前面] 有时候会与同事共享文件,正常人的操作是鼠标右键,点击共享.其实有个装逼的方法,用python的一行代码快速实现基于http服务的共享方式. [效果如下] [示例代码] 在cmd窗口进入想 ...
- 【LiteOS】STM32F103-LiteOS移植教程(详细篇)
总览 本文基于STM32F103C8T6,详细讲述华为LiteOS的移植过程.开发工具是MDK5.LiteOS官方已经适配过cortex M系列内核的单片机,因此移植过程非常简单. LiteOS有两种 ...
- NAT回流(Twice NAT)Hairping 参数详解
内网用户需要通过域名访问内网的服务器,一般商用环境是无法访问的,需要经过以下配置,原理不说了,直接说配置. nat (inside,inside) source dynamic inside-net ...