一、介绍
todolist,即待办事项。在windows android ios上参考微软家出的那个To-Do应用,大概就是那样的。我这个更简单,功能只有“待办” “已完成”两项,并且是在浏览器打开的。
二、界面和文件结构这些...
实际在浏览器中的网页如下:
在subline中的文件结构有index.html、index.css、index.js各一个,如下图:
三、程序
参考注释即可看懂。
(1)index.html文件
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <!-- http-equiv指定文档的内容类型和编码类型 --> 5 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 6 <!-- name属性 视图和描述 name+content --> 7 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> 8 <title>ToDoList—最简单的待办事项列表</title> 9 <meta name="description" content="ToDoList无须注册即可使用,数据存储在用户浏览器的html5本地数据库里,是最简单最安全的待办事项列表应用!" /> 10 <!-- 外接式css --> 11 <link rel="stylesheet" href="./index.css"> 12 </head> 13 <body> 14 <!-- 头部:在这添加任务 --> 15 <div class="header"> 16 <div class="box"> 17 <form action="javascript:postaction()" id="form"> 18 <!-- for将label标签绑定到input --> 19 <label for="title">ToDoList</label> 20 <!-- required规定提交表单之前有必填字段 autocomplete:自动补齐--> 21 <input type="text" id="title" name="title" placeholder="添加ToDo" required="required" autocomplete="off" /> 22 </form> 23 </div> 24 </div> 25 <!-- 主体:在这进行任务和已完成 --> 26 <div class="content"> 27 <h2 onclick="save()">正在进行 <span id="todocount"></span></h2> 28 <ol id="todolist" class="demo-box"> 29 </ol> 30 <h2>已经完成 <span id="donecount"></span></h2> 31 <ul id="donelist"> 32 </ul> 33 </div> 34 <!-- 脚部:印记和全清除按钮 --> 35 <div class="footer"> 36 Copyright © 2018 todolist.cn <a href="javascript:clear();">clear</a> 37 </div> 38 <!-- 外接式js --> 39 <script type="text/javascript" src="./index.js"></script> 40 </body> 41 </html>
(2)index.css文件
1 /*清除默认样式 并设置简单样式*/ 2 body { 3 margin: 0; 4 padding: 0; 5 font-size: 16px; 6 background: #CDCDCD; 7 } 8 9 .header { 10 height: 50px; 11 background: #333; 12 /*background: rgba(47,47,47,0.98);*/ 13 } 14 15 .header .box,.content{ 16 width: 700px; 17 padding: 0 10px; 18 margin: 0 auto; 19 } 20 /*.content{ 21 margin: 0 auto; 22 }*/ 23 24 label { 25 float: left; 26 width: 100px; 27 line-height: 50px; 28 color: #DDD; 29 font-size: 24px; 30 /*鼠标悬停样式 一只手*/ 31 cursor: pointer; 32 font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; 33 } 34 35 .header input { 36 float: right; 37 width: 60%; 38 height: 24px; 39 margin-top: 12px; 40 /*首行缩进10px*/ 41 text-indent: 10px; 42 /*圆角边框 好看不止一点点*/ 43 border-radius: 5px; 44 /*盒子阴影 inset内阴影*/ 45 box-shadow: 0 1px 0 rgba(255,255,255,0.24), 0 1px 6px rgba(0,0,0,0.45) inset; 46 border: none 47 } 48 /*选中输入框 轮廓的宽度为0*/ 49 input:focus { 50 outline-width: 0; 51 } 52 /*父相子绝*/ 53 h2 { 54 position: relative; 55 } 56 57 span { 58 position: absolute; 59 top: 2px; 60 right: 5px; 61 /*设置行内块 有宽高*/ 62 display: inline-block; 63 padding: 0 5px; 64 height: 20px; 65 border-radius: 20px; 66 background: #E6E6FA; 67 line-height: 22px; 68 text-align: center; 69 color: #666; 70 font-size: 14px; 71 } 72 /*清除ol和ul标签的默认样式*/ 73 ol,ul { 74 padding: 0; 75 list-style: none; 76 } 77 78 li { 79 height: 32px; 80 line-height: 32px; 81 background: #fff; 82 position: relative; 83 margin-bottom: 10px; 84 padding: 0 45px; 85 border-radius: 3px; 86 border-left: 5px solid #629A9C; 87 box-shadow: 0 1px 2px rgba(0,0,0,0.07); 88 } 89 /*任务单选框*/ 90 li input { 91 position: absolute; 92 top: 2px; 93 left: 10px; 94 width: 22px; 95 height: 22px; 96 cursor: pointer; 97 } 98 /*任务内容*/ 99 p { 100 margin: 0; 101 } 102 /*任务内容的文本输入框,用来修改里面的内容*/ 103 li p input { 104 top: 3px; 105 left: 40px; 106 width: 70%; 107 height: 20px; 108 line-height: 14px; 109 text-indent: 5px; 110 font-size: 14px; 111 } 112 113 ul li { 114 border-left: 5px solid #999; 115 /*不透明度 0完全透明~1完全不透明*/ 116 opacity: 0.5; 117 } 118 /*勾选按钮*/ 119 li a { 120 position: absolute; 121 top: 2px; 122 right: 5px; 123 display: inline-block; 124 width: 14px; 125 height: 12px; 126 border-radius: 14px; 127 border: 6px double #FFF; 128 background: #CCC; 129 line-height: 14px; 130 text-align: center; 131 color: #FFF; 132 font-weight: bold; 133 font-size: 14px; 134 cursor: pointer; 135 } 136 137 .footer { 138 color: #666; 139 font-size: 14px; 140 text-align: center; 141 } 142 143 .footer a { 144 /*color: #666;*/ 145 text-decoration: none; 146 color: #999; 147 }
(3)index.js文件
1 function clear() { 2 localStorage.clear(); 3 load(); 4 } 5 6 function postaction() { 7 // 获取title节点 8 var title = document.getElementById("title"); 9 if (title.value.trim() == "") { 10 alert("内容不能为空"); 11 } else { 12 var data = loadData(); 13 var todo = { "title": title.value, "done": false }; 14 data.push(todo); 15 saveData(data); 16 var form = document.getElementById("form"); 17 form.reset(); 18 load(); 19 } 20 } 21 22 function loadData() { 23 var collection = localStorage.getItem("todo"); 24 if (collection != null) { 25 return JSON.parse(collection); 26 } else return []; 27 } 28 29 function saveSort() { 30 var todolist = document.getElementById("todolist"); 31 var donelist = document.getElementById("donelist"); 32 var ts = todolist.getElementsByTagName("p"); 33 var ds = donelist.getElementsByTagName("p"); 34 var data = []; 35 for (i = 0; i < ts.length; i++) { 36 var todo = { "title": ts[i].innerHTML, "done": false }; 37 data.unshift(todo); 38 } 39 for (i = 0; i < ds.length; i++) { 40 var todo = { "title": ds[i].innerHTML, "done": true }; 41 data.unshift(todo); 42 } 43 saveData(data); 44 } 45 46 function saveData(data) { 47 localStorage.setItem("todo", JSON.stringify(data)); 48 } 49 50 function remove(i) { 51 var data = loadData(); 52 var todo = data.splice(i, 1)[0]; 53 saveData(data); 54 load(); 55 } 56 57 function update(i, field, value) { 58 var data = loadData(); 59 var todo = data.splice(i, 1)[0]; 60 todo[field] = value; 61 data.splice(i, 0, todo); 62 saveData(data); 63 load(); 64 } 65 66 function edit(i) { 67 load(); 68 var p = document.getElementById("p-" + i); 69 title = p.innerHTML; 70 p.innerHTML = "<input id='input-" + i + "' value='" + title + "' />"; 71 var input = document.getElementById("input-" + i); 72 input.setSelectionRange(0, input.value.length); 73 input.focus(); 74 input.onblur = function() { 75 if (input.value.length == 0) { 76 p.innerHTML = title; 77 alert("内容不能为空"); 78 } else { 79 update(i, "title", input.value); 80 } 81 }; 82 } 83 84 function load() { 85 var todolist = document.getElementById("todolist"); 86 var donelist = document.getElementById("donelist"); 87 var collection = localStorage.getItem("todo"); 88 if (collection != null) { 89 var data = JSON.parse(collection); 90 var todoCount = 0; 91 var doneCount = 0; 92 var todoString = ""; 93 var doneString = ""; 94 for (var i = data.length - 1; i >= 0; i--) { 95 if (data[i].done) { 96 doneString += "<li draggable='true'><input type='checkbox' οnchange='update(" + i + ",\"done\",false)' checked='checked' />" + 97 "<p id='p-" + i + "' οnclick='edit(" + i + ")'>" + data[i].title + "</p>" + 98 "<a href='javascript:remove(" + i + ")'>-</a></li>"; 99 doneCount++; 100 } else { 101 todoString += "<li draggable='true'><input type='checkbox' οnchange='update(" + i + ",\"done\",true)' />" + 102 "<p id='p-" + i + "' οnclick='edit(" + i + ")'>" + data[i].title + "</p>" + 103 "<a href='javascript:remove(" + i + ")'>-</a></li>"; 104 todoCount++; 105 } 106 }; 107 todocount.innerHTML = todoCount; 108 todolist.innerHTML = todoString; 109 donecount.innerHTML = doneCount; 110 donelist.innerHTML = doneString; 111 } else { 112 todocount.innerHTML = 0; 113 todolist.innerHTML = ""; 114 donecount.innerHTML = 0; 115 donelist.innerHTML = ""; 116 } 117 } 118 119 window.onload = load; 120 121 // window.addEventListener("storage", load, false);