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代码:
1 <body> 2 <header> 3 <section> 4 <label for="title">todolist</label> 5 <input type="text" id="title" name="title" placeholder="添加todo" required="required" autocomplete="off" /> 6 </section> 7 </header> 8 <section> 9 <h2>正在进行 <span id="todocount"></span></h2> 10 <ol id="todolist" class="demo-box"> 11 12 </ol> 13 <h2>已经完成 <span id="donecount"></span></h2> 14 <ul id="donelist"> 15 16 </ul> 17 </section> 18 <footer> 19 copyright © 2019 20 </footer> 21 </body>
1 body { 2 margin: 0; 3 padding: 0; 4 font-size: 16px; 5 background: #cdcdcd; 6 } 7 8 header { 9 height: 50px; 10 background: #333; 11 background: rgba(47, 47, 47, 0.98); 12 } 13 14 section { 15 margin: 0 auto; 16 } 17 18 label { 19 float: left; 20 width: 100px; 21 line-height: 50px; 22 color: #ddd; 23 font-size: 24px; 24 cursor: pointer; 25 font-family: "helvetica neue", helvetica, arial, sans-serif; 26 } 27 28 header input { 29 float: right; 30 width: 60%; 31 height: 24px; 32 margin-top: 12px; 33 text-indent: 10px; 34 border-radius: 5px; 35 box-shadow: 0 1px 0 rgba(255, 255, 255, 0.24), 0 1px 6px rgba(0, 0, 0, 0.45) inset; 36 border: none 37 } 38 39 input:focus { 40 outline-width: 0 41 } 42 43 h2 { 44 position: relative; 45 } 46 47 span { 48 position: absolute; 49 top: 2px; 50 right: 5px; 51 display: inline-block; 52 padding: 0 5px; 53 height: 20px; 54 border-radius: 20px; 55 background: #e6e6fa; 56 line-height: 22px; 57 text-align: center; 58 color: #666; 59 font-size: 14px; 60 } 61 62 ol, 63 ul { 64 padding: 0; 65 list-style: none; 66 } 67 68 li input { 69 position: absolute; 70 top: 2px; 71 left: 10px; 72 width: 22px; 73 height: 22px; 74 cursor: pointer; 75 } 76 77 p { 78 margin: 0; 79 } 80 81 li p input { 82 top: 3px; 83 left: 40px; 84 width: 70%; 85 height: 20px; 86 line-height: 14px; 87 text-indent: 5px; 88 font-size: 14px; 89 } 90 91 li { 92 height: 32px; 93 line-height: 32px; 94 background: #fff; 95 position: relative; 96 margin-bottom: 10px; 97 padding: 0 45px; 98 border-radius: 3px; 99 border-left: 5px solid #629a9c; 100 box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); 101 } 102 103 ol li { 104 cursor: move; 105 } 106 107 ul li { 108 border-left: 5px solid #999; 109 opacity: 0.5; 110 } 111 112 li a { 113 position: absolute; 114 top: 2px; 115 right: 5px; 116 display: inline-block; 117 width: 14px; 118 height: 12px; 119 border-radius: 14px; 120 border: 6px double #fff; 121 background: #ccc; 122 line-height: 14px; 123 text-align: center; 124 color: #fff; 125 font-weight: bold; 126 font-size: 14px; 127 cursor: pointer; 128 } 129 130 footer { 131 color: #666; 132 font-size: 14px; 133 text-align: center; 134 } 135 136 footer a { 137 color: #666; 138 text-decoration: none; 139 color: #999; 140 } 141 142 @media screen and (max-device-width: 620px) { 143 section { 144 width: 96%; 145 padding: 0 2%; 146 } 147 } 148 149 @media screen and (min-width: 620px) { 150 section { 151 width: 600px; 152 padding: 0 10px; 153 } 154 }
接下来开始写我们自己的js代码
将多次使用的代码封装成函数,方便使用
①获取本地存储的数据。如果本地有数据则直接获取过来,没有数据的话就返回一个空数组
1 function getdate() { 2 var data = localstorage.getitem("todolist"); // 将获取到的数据赋给data 3 if(data !== null) { // 如果本地有数据,则返回数据 4 return json.parse(data); // 本地存储只能存储字符串,所以要想获取里边的数据就必须将字符串转换为数组形式返回 5 } else { 6 return []; // 如果本地没有数据,则返回一个空数组 7 } 8 }
②保存本地存储数据
1 function savedate(data) { 2 // 用json.stringify()将数组转化成字符串保存到本地存储 3 localstorage.setitem("todolist", json.stringify(data)); 4 }
③渲染页面 加载数据
先将本地存储数据获取过来;将他们遍历(遍历之前先将列表清空),看他们是否已经被完成(通过数组里我们自己添加的done的值为true还是false来判断),如果已经被完成则添加到ul列表,否则添加进ol列表里;同时声明两个变量来保存已完成和未完成事项的个数
1 function load() { 2 var data = getdate(); // 先获取本地存储数据 3 4 // 遍历本地存储数据 将他们添加到列表中 5 $("ol, ul").empty(); // 遍历之前先清空列表 6 var donecount = 0; // 已经完成的个数 7 var todocount = 0; // 正在进行的个数 8 $.each(data, function(i, ele) { // i为索引 ele为遍历对象 9 // 如果复选框被选中(已完成done: true)添加到ul里,未被选中(未完成done: false)添加到ol里 10 if(ele.done) { 11 $("ul").prepend("<li><input type='checkbox' checked='checked' > <p>" + ele.title + "</p> <a href='javascript:;' index=" + i + "></a></li>"); 12 donecount++; // 每添加一个li,已完成数加一 13 } else { 14 $("ol").prepend("<li><input type='checkbox'> <p>" + ele.title + "</p> <a href='javascript:;' index=" + i + "></a></li>"); 15 todocount++; 16 } 17 }) 18 $("#donecount").text(donecount); 19 $("#todocount").text(todocount); 20 }
1. 用户输入待办事项按下回车,将事项添加进列表
给文本框绑定键盘按下事件,通过ascii值来判断用户是否按下了回车(回车的ascii值为13);
不能直接在本地存储里更改数据,所以要先获取数据(数组形式),把数组进行更新数据(把最新数据追加给数组),再保存到本地存储;
然后对页面进行重新渲染 更新数据
1 load(); // 第一步先渲染页面,不然一开始刷新页面时列表不显示 2 $("#title").on("keydown", function(event) { 3 if(event.keycode === 13) { 4 if($(this).val() !== "") { 5 var data = getdate(); // 获取本地存储数据 6 // 把数组进行更新数据,把最新数据追加给数组 7 data.push({title: $(this).val(), done: false}); 8 savedate(data); // 保存到本地存储 9 load(); // 渲染加载到页面 10 $(this).val(""); 11 } 12 } 13 })
2. 删除待办事项
先获取本地存储数据;
用attr获取自定义属性index(索引)得到用户点击的第几个事项,通过索引删除数组里对应的那组数据;
将更新过的数组保存到本地存储 再渲染给页面
1 $("ol, ul").on("click", "a", function() { 2 var data = getdate(); // 获取本地数据(data是局部变量,不用担心冲突) 3 var index = $(this).attr("index"); // 用attr获取自定义属性index,得到索引 4 // splice(index, num)删除数组对象 index为开始删除的位置,num为删除几个 5 data.splice(index, 1); 6 savedate(data); 7 load(); 8 })
3. 用户点击复选框来选择事项已完成或未完成
获取本地存储数据;
通过复选框的兄弟a的index属性来获取用户点击的事项的索引(index),将第index个数据的done属性值修改为复选框的值;
将更新过的数组保存到本地存储 再渲染给页面
1 $("ol, ul").on("click", "input", function() { 2 var data = getdate(); 3 // 利用a获取用户点击的第几个复选框 4 var index = $(this).siblings("a").attr("index"); 5 // 修改数据:data[索引].属性名 获取固有属性用prop 6 data[index].done = $(this).prop("checked"); 7 savedate(data); 8 load(); 9 })
详细js代码:
1 $(function() { 2 load(); // 先渲染页面,不然一开始刷新页面时列表不显示 3 // 1、绑定键盘按下事件 4 $("#title").on("keydown", function(event) { 5 if(event.keycode === 13) { // 是否按下了回车 回车的ascii值为13 6 if($(this).val() == "") { 7 alert("请输入事项内容!") 8 } else { 9 // 不能直接在本地存储里改数据,所以要先获取数据,然后改变数组,再保存到本地 10 var data = getdate(); // 获取本地存储数据 11 // 把数组进行更新数据,把最新数据追加给数组 12 data.push({title: $(this).val(), done: false}); 13 savedate(data); // 保存到本地存储 14 load(); // 渲染加载到页面 15 $(this).val(""); 16 } 17 } 18 }) 19 //2、删除待办事项 20 $("ol, ul").on("click", "a", function() { 21 var data = getdate(); // 获取本地数据 22 var index = $(this).attr("index"); // 用attr获取自定义属性,得到索引 23 // splice(index, num)删除数组对象 index为开始删除的位置,num为删除几个 24 data.splice(index, 1); 25 savedate(data); // 删除后在把data保存到本地存储 26 load(); // 重新渲染页面 27 }) 28 //3、正在进行和已完成 29 $("ol, ul").on("click", "input", function() { 30 var data = getdate(); // 获取数据 31 // 获取用户点击的第几个按钮,利用a 32 var index = $(this).siblings("a").attr("index"); 33 // 修改数据 data[索引].属性名 获取固有属性用prop 34 data[index].done = $(this).prop("checked"); 35 savedate(data); // 保存到本地存储 36 load(); // 渲染页面 37 }) 38 // 获取本地存储数据 39 function getdate() { 40 var data = localstorage.getitem("todolist"); 41 if(data !== null) { // 如果本地有数据,则返回数据 42 return json.parse(data); // 本地存储只能存储字符串,所以要将字符串转换为数组形式返回 43 } else { // 如果本地没有数据,则返回一个空数组 44 return []; 45 } 46 } 47 // 保存本地存储数据 48 function savedate(data) { 49 // 用json.stringify()将数组转化成字符串保存到本地存储 50 localstorage.setitem("todolist", json.stringify(data)); 51 } 52 // 渲染加载数据 53 function load() { 54 var data = getdate(); // 先获取本地存储数据 55 // 遍历本地存储数据 将他们添加到列表中 56 $("ol, ul").empty(); // 遍历之前先清空列表 57 var donecount = 0; // 已经完成的个数 58 var todocount = 0; // 正在进行的个数 59 $.each(data, function(i, ele) { // i是索引 ele为遍历对象 60 // 如果复选框被选中(已完成)添加到ul里,没被选中(未完成)添加到ol里 61 if(ele.done) { 62 $("ul").prepend("<li><input type='checkbox' checked='checked' > <p>" + ele.title + "</p> <a href='javascript:;' index=" + i + "></a></li>"); 63 donecount++; 64 } else { 65 // 将数据添加进列表里 66 $("ol").prepend("<li><input type='checkbox'> <p>" + ele.title + "</p> <a href='javascript:;' index=" + i + "></a></li>"); 67 todocount++; 68 } 69 }) 70 $("#donecount").text(donecount); 71 $("#todocount").text(todocount); 72 } 73 })