15 JS应用-todolist任务
需求
1. 将用户输入添加至待办项
2. 可以对todolist进行分类(待办项和已完成组),用户勾选既将待办项分入已完成组
3. todolist的每一项可删除和编辑
4. 下方有clear按钮,并清空所有todolist项
html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> 6 <title>ToDoList—最简单的待办事项列表</title> 7 <meta name="description" content="ToDoList无须注册即可使用!" /> 8 <link rel="stylesheet" href="mystyle.css"> 9 </head> 10 <body> 11 <div class="header"> 12 <div class="box"> 13 <form action="javascript:postaction()" id="form"> 14 <label for="title">ToDoList</label> 15 <input type="text" id="title" name="title" placeholder="添加ToDo" required="required" autocomplete="off" /> 16 </form> 17 </div> 18 </div> 19 <div class="content"> 20 <h2 onclick="save()">正在进行 <span id="todocount"></span></h2> 21 <ol id="todolist" class="demo-box"> 22 </ol> 23 <h2>已经完成 <span id="donecount"></span></h2> 24 <ul id="donelist"> 25 </ul> 26 </div> 27 <div class="footer"> 28 Copyright © 2019 todolist.cn <a href="javascript:clear();">clear</a> 29 </div> 30 <script type="text/javascript" src="myjs.js"></script> 31 </body> 32 </html>
css
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 .header .box,.content{ 15 width: 600px; 16 padding: 0 10px; 17 margin: 0 auto; 18 } 19 .content{ 20 margin: 0 auto; 21 } 22 23 label { 24 float: left; 25 width: 100px; 26 line-height: 50px; 27 color: #DDD; 28 font-size: 24px; 29 cursor: pointer; 30 font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; 31 } 32 33 .header input { 34 float: right; 35 width: 60%; 36 height: 24px; 37 margin-top: 12px; 38 text-indent: 10px; 39 border-radius: 5px; 40 box-shadow: 0 1px 0 rgba(255,255,255,0.24), 0 1px 6px rgba(0,0,0,0.45) inset; 41 border: none 42 } 43 44 input:focus { 45 outline-width: 0 46 } 47 48 h2 { 49 position: relative; 50 } 51 52 span { 53 position: absolute; 54 top: 2px; 55 right: 5px; 56 display: inline-block; 57 padding: 0 5px; 58 height: 20px; 59 border-radius: 20px; 60 background: #E6E6FA; 61 line-height: 22px; 62 text-align: center; 63 color: #666; 64 font-size: 14px; 65 } 66 67 ol,ul { 68 padding: 0; 69 list-style: none; 70 } 71 72 li input { 73 position: absolute; 74 top: 2px; 75 left: 10px; 76 width: 22px; 77 height: 22px; 78 cursor: pointer; 79 } 80 81 p { 82 margin: 0; 83 } 84 85 li p input { 86 top: 3px; 87 left: 40px; 88 width: 70%; 89 height: 20px; 90 line-height: 14px; 91 text-indent: 5px; 92 font-size: 14px; 93 } 94 95 li { 96 height: 32px; 97 line-height: 32px; 98 background: #fff; 99 position: relative; 100 margin-bottom: 10px; 101 padding: 0 45px; 102 border-radius: 3px; 103 border-left: 5px solid #629A9C; 104 box-shadow: 0 1px 2px rgba(0,0,0,0.07); 105 } 106 107 ol li { 108 cursor: move; 109 } 110 111 ul li { 112 border-left: 5px solid #999; 113 opacity: 0.5; 114 } 115 116 li a { 117 position: absolute; 118 top: 2px; 119 right: 5px; 120 display: inline-block; 121 width: 14px; 122 height: 12px; 123 border-radius: 14px; 124 border: 6px double #FFF; 125 background: #CCC; 126 line-height: 14px; 127 text-align: center; 128 color: #FFF; 129 font-weight: bold; 130 font-size: 14px; 131 cursor: pointer; 132 } 133 134 .footer { 135 color: #666; 136 font-size: 14px; 137 text-align: center; 138 } 139 140 .footer a { 141 color: #666; 142 text-decoration: none; 143 color: #999; 144 }
JS
1 function $(id) { 2 return document.getElementById(id); 3 } 4 5 function clear() { 6 localStorage.clear(); 7 load(); 8 } 9 10 function postaction() { 11 if($('title').value == ''){ 12 alert('不可为空!') 13 }else{ 14 var data = loadData(); 15 var todo = {'title':$('title').value,'done':false}; 16 data.push(todo); 17 saveData(data); 18 $('form').reset(); 19 load(); 20 } 21 } 22 23 function loadData() { 24 var collection = localStorage.getItem('todo'); 25 if(collection){ 26 return JSON.parse(collection); 27 }else{ 28 return []; 29 } 30 } 31 32 function saveData(data) { 33 localStorage.setItem('todo',JSON.stringify(data)) 34 } 35 36 function remove(i) { 37 var data = loadData(); 38 data.splice(i,1); 39 saveData(data); 40 load(); 41 } 42 43 function update(i,field,value) { 44 var data = loadData(); 45 var todo = data.splice(i,1)[0]; 46 todo[field] = value; 47 data.splice(i,0,todo); 48 saveData(data); 49 load(); 50 } 51 52 function edit(i) { 53 load(); 54 var p = document.getElementById('p-'+i); 55 title = p.innerHtml; 56 p.innerHTML = "<input id='input-" + i + "' value='" + title + "' />"; 57 var input = $("input-" + i); 58 input.setSelectionRange(0,input.value.length); // 选中value 59 input.focus(); 60 input.onblur = function () { 61 if(input.value.length == 0){ 62 p.innerHTML = title; 63 alert('不能为空!'); 64 }else{ 65 update(i,'title',input.value); 66 } 67 } 68 } 69 70 function load() { 71 var todolist = $('todolist'); 72 var donelist = $('donelist'); 73 var collection = localStorage.getItem('todo'); 74 if(collection != null){ 75 var data = JSON.parse(collection); 76 var todoCount = 0; 77 var doneCount = 0; 78 var todoString = ""; 79 var doneString = ""; 80 for(var i = data.length - 1;i >= 0; i--){ 81 if(data[i].done){ 82 doneString += "<li draggable='true'><input type='checkbox' onchange='update(" + i + ",\"done\",false)' checked='checked' />" + 83 "<p id='p-" + i + "' onclick='edit(" + i + ")'>" + data[i].title + "</p>" + 84 "<a href='javascript:remove(" + i + ")'>-</a></li>"; 85 doneCount++; 86 }else{ 87 todoString += "<li draggable='true'><input type='checkbox' onchange='update(" + i + ",\"done\",true)' />" + 88 "<p id='p-" + i + "' onclick='edit(" + i + ")'>" + data[i].title + "</p>" + 89 "<a href='javascript:remove(" + i + ")'>-</a></li>"; 90 todoCount++; 91 } 92 } 93 todocount.innerHTML = todoCount; 94 todolist.innerHTML = todoString; 95 donecount.innerHTML = doneCount; 96 donelist.innerHTML = doneString; 97 }else{ 98 todocount.innerHTML = 0; 99 todolist.innerHTML = ""; 100 donecount.innerHTML = 0; 101 donelist.innerHTML = ""; 102 } 103 } 104 105 window.onload = load;
夕闻道不如朝闻道