一,demo背景:
1,可以熟悉原生js
2,平时不知道自己学完js要做些什么东西的小伙伴
3,自己写的,可以当做自己的作品
4,为广大想练习练习原生js的贡献一个素材
二,实现功能:
1,新建/删除任务功能
2,设置/取消星标任务功能
3,设置/取消任务完成功能
4,过期任务自动删除功能(本例期限设置为了2天)
5,任务超时后禁止操作功能
三, 逻辑实现:
把新建的一个任务就抽象成一个对象,该对象里面有自己的创建时间,内容,结束事件,是否为星标任务等等。然后这个对象字符串化存放到localStorage
里,每次在要数据时,都从localStorage
里面取出数据。最后就是用各种的数据进行If..else
判断,渲染Dom。(过程中用到了很多字符串,数组方法,可以增加你对这些方法的熟练度)
四,demo效果展示:
完成了的任务:
星标任务:
五,代码展示:
html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>LocalNotepad</title> <link rel="stylesheet" type="text/css" href="font-awesome-4.5.0/css/font-awesome.css"> <link rel="stylesheet" type="text/css" href="css/style.css"> </head> <body> <div id="m-hidden"></div> <div id="pub-box"> <textarea class="content" placeholder="为你添加新的任务"></textarea> <div class="but-box"> <div class="time-box"> <p class="static">任务起始时间 :</p> <p class="time-begin"> <input type="text" class="t-b-year" placeholder=""><time>年</time> <input type="text" class="t-b-mon" placeholder=""><time>月</time> <input type="text" class="t-b-day" placeholder=""><time>日</time> </p> <p class="static">务结束时间 :</p> <p class="time-end"> <input type="text" class="t-b-year"><time>年</time> <input type="text" class="t-b-mon"><time>月</time> <input type="text" class="t-b-day"><time>日</time> </p> </div> <div class="btn"> <button class="reset">重置</button> <button class="add">添加</button> </div> </div> </div> <div id="content"> </div> <script type="text/javascript" src="js/Tool.js"></script> <script type="text/javascript" src="js/script.js"></script> </body> </html>
css:
* { margin: 0; padding: 0; font-family: "Microsoft YaHei" } html,body { height: 100%; } body { background: #fafc2a; background: url('../images/1.jpg') no-repeat 0 -50px; background-size: 100%; background-attachment: fixed; } a {text-decotation: none;} strong {font-weight: normal;} i,b {font-style: none;} /*样式开始*/ #m-hidden { height: 1px; background: transparent; } #pub-box { width: 1000px; height: 220px; background: rgba(0, 0, 0, 0.5); box-sizing: border-box; margin: 0 auto; padding: 20px; margin-top: -140px; transition: .6s; } #pub-box:hover { margin-top: -1px; transition: .6s; } #pub-box .content { width: 100%; height: 120px; background: rgba(246, 248, 41, 0.5); resize: none; outline: none; border: none; box-sizing: border-box; padding: 10px; } #pub-box .but-box:after { content:''; display: block; width: 0; height: 0; clear: both; } #pub-box .but-box .time-box{ float: left; } #pub-box .but-box .time-box:after { content:''; display: block; width: 0; height: 0; clear: both; } #pub-box .but-box .time-box p { float: left; margin-top: 25px; color: #fafc2a; } #pub-box .but-box .time-box .time-begin{} #pub-box .but-box .time-box .time-end{} #pub-box .but-box .time-box .time-begin, #pub-box .but-box .time-box .time-end { margin-right: 30px; } #pub-box .but-box .time-box .time-begin input, #pub-box .but-box .time-box .time-end input, #pub-box .but-box .time-box .time-begin time, #pub-box .but-box .time-box .time-end time { float: left; margin: 0 3px; } #pub-box .but-box .time-box .time-begin input, #pub-box .but-box .time-box .time-end input { display: block; width: 40px; height: 22px; text-align: center; outline: none; background: rgba(246, 248, 41, 0.3); border: none; color: #000; } #pub-box .but-box .btn { float: right; } #pub-box .but-box button { display: block; float: right; width: 70px; height: 30px; outline: none; border: none; margin-top: 20px; margin-left: 20px; letter-spacing: 2px; background: #fafc2a; color: #000; } #pub-box .but-box button:hover { background: #f8fa5b; color: #555; } #content { width: 1000px; height: auto; margin: 50px auto 0 auto; } #content .c-b{ position: relative; width: 100%; background: rgba(0, 0, 0, 0.5); margin-bottom: 20px; box-sizing: border-box; padding: 20px; color: #fafc2a; } #content .red-star { position: absolute; width: 20px; height: 20px; top: 0px; left: 0px; text-align: center; line-height: 23px; } #content .fa-star { color: #fafc2a; } #content .ms-cont-b { width: 100%; } #content .ms-cont-b:after { content:''; display: block; width: 0; height: 0; clear: both; } #content .ms-cont-b .ms-cont { float: left; max-width: 700px; word-break: break-all; font-size: 18px; letter-spacing: 1px; } #content .ms-icon { float: right; width: 80px; height: 80px; text-align: center; font-size: 80px; line-height: 80px; /*color: #d71d2e;*/ color: #fafc2a; } #content .ms-b { width: 100%; margin-top: 20px; } #content .ms-b:after { content:''; display: block; width: 0; height: 0; clear: both; } #content .ms-b .ms-time { width: 600px; float: left; margin-top: 25px; } #content .ms-b .ms-time:after{ content:''; display: block; width: 0; height: 0; clear: both; } #content .ms-b .ms-btn { float: right; // display: none; } #content .ms-b .ms-time .create-t { float: left; } #content .ms-b .ms-time .set-t{ float:left; margin-left: 50px; } #content .ms-b .ms-btn button{ display: block; float: right; width: 70px; height: 30px; outline: none; border: none; margin-top: 20px; margin-left: 20px; letter-spacing: 2px; } #content .ms-b .ms-btn button.star { width: 120px; background: #fafc2a; color: #000; } #content .ms-b .ms-btn button.del { background: #fafc2a; color: #000; } #content .ms-b .ms-btn button.finished { width: 100px; background: #fafc2a; color: #000; } #content .ms-b .ms-btn button.del:hover { background: #f0f204; } #content .ms-b .ms-btn button.star:hover { background: #f0f204; } #content .ms-b .ms-btn button.finished:hover { background: #f0f204; }
js:
(function() { var textContent = document.querySelector('#pub-box .content'), beginTimes = document.querySelectorAll('#pub-box .time-begin input'), endTimes = document.querySelectorAll('#pub-box .time-end input'), reset = document.querySelector('#pub-box .btn .reset'), add = document.querySelector('#pub-box .btn .add'), content = document.querySelector('#content'), temp = localStorage.getItem('D'), id, data, lcdata; if (!temp) { data = []; } else { data = JSON.parse(temp); } /*插入任务*/ function createAriticle(id, text, createTime, msTime) { var str = '<article class="c-b" data-id="' + id + '">' + '<div class="red-star"></div>' + '<div class="ms-cont-b">' + '<div class="ms-cont">' + text + '</div>' + '<div class="ms-icon"></div>' + '</div>' + '<div class="ms-b">' + '<div class="ms-time">' + '<p class="create-t">创建于:<span>' + createTime + '</span></p>' + '<p class="set-t">' + msTime +'</p>' + '</div>' + '<div class="ms-btn">' + '<button class="del" onclick="deletArticle(this)">删除</button>' + '<button class="star" onclick="addRedStar(this)">设为星标任务</button>' + '<button class="finished" onclick="isFinish(this)">确认完成</button>' + '</div>' + '</div>' + '</article>' content.innerHTML = str + content.innerHTML; } /*删除任务*/ function deletArticle(self) { var id = self.parentNode.parentNode.parentNode.getAttribute('data-id'); var parent = self.parentNode.parentNode.parentNode.parentNode; var arts = document.querySelectorAll('.c-b'); var s; for (var i = 0; i < arts.length; i++) { if (arts[i].getAttribute('data-id') == id) { parent.removeChild(arts[i]); for (var j = 0; j < data.length; j++) { if (data[j].id == id) { data.splice(j,1); } } } } s = JSON.stringify(data); localStorage.setItem('D', s); } window.deletArticle = deletArticle; /*添加星标任务*/ function addRedStar(self) { var id = self.parentNode.parentNode.parentNode.getAttribute('data-id'); var str; for (var i = 0; i < data.length; i++) { if (data[i].id == id) { if (!data[i].star) { self.parentNode.parentNode.parentNode.children[0].className = 'red-star fa fa-star'; self.innerHTML = "取消星标任务"; data[i].star = true; } else { self.parentNode.parentNode.parentNode.children[0].className = 'red-star'; self.innerHTML = "设为星标任务"; data[i].star = false; } } } str = JSON.stringify(data); localStorage.setItem('D', str); } window.addRedStar = addRedStar; /*确认任务完成操作*/ function isFinish(self) { var id = self.parentNode.parentNode.parentNode.getAttribute('data-id'); var str; for (var i = 0; i < data.length; i++) { if (data[i].id == id) { if (data[i].finished == 0) { self.parentNode.parentNode.previousSibling.children[1].className = 'ms-icon fa fa-check'; self.innerHTML = "取消完成"; data[i].finished = 1; } else if (data[i].finished == 1) { self.parentNode.parentNode.previousSibling.children[1].className = 'ms-icon'; self.innerHTML = "确认完成"; data[i].finished = 0; } else { return; } } } str = JSON.stringify(data); localStorage.setItem('D', str); } window.isFinish = isFinish; /*页面加载完,向页面加载默认任务起始时间*/ function addDefaultTime() { var date = new Date(); beginTimes[0].placeholder = date.getFullYear(); beginTimes[1].placeholder = date.getMonth() + 1; beginTimes[2].placeholder = date.getDate(); } addDefaultTime(); /*加载任务*/ function loadThing() { var arr, length, sets, finishs, arts, stars, now = new Date().getTime(), d = localStorage.getItem('D'); if (!d) { console.log(d); return; } arr = JSON.parse(d); length = arr.length; for (var m = 0; m < length; m++) { if ((now - arr[m].id) > 259200000) { arr.splice(m, 1); } } if (!arr.length) { return; } for (var i = 0; i < length; i++) { createAriticle(arr[i].id, arr[i].text, arr[i].createTime, arr[i].msTime); } arts = document.querySelectorAll('.c-b'); finishs = document.querySelectorAll('.finished'); for (var i = 0; i < length; i++) { if (arr[i].star) { for (var j = 0; j < arts.length; j++) { if (arts[j].getAttribute('data-id') == arr[i].id) { arts[j].children[0].className = 'red-star fa fa-star'; arts[j].getElementsByClassName('star')[0].innerHTML = '取消星标任务'; } } } if ((arr[i].em - arr[i].bm) < 0) { arr[i].finished = 2; } if (arr[i].finished == 0) { for (var k = 0; k < arts.length; k++) { if (arts[k].getAttribute('data-id') == arr[i].id) { arts[k].getElementsByClassName('ms-icon')[0].className = 'ms-icon'; arts[k].getElementsByClassName('finished')[0].innerHTML = '确认完成'; } } } else if (arr[i].finished == 1) { for (var t = 0; t < arts.length; t++) { if (arts[t].getAttribute('data-id') == arr[i].id) { arts[t].getElementsByClassName('ms-icon')[0].className = 'ms-icon fa fa-check'; arts[t].getElementsByClassName('finished')[0].innerHTML = '取消完成'; } } } else if (arr[i].finished == 2) { for (var n = 0; n < arts.length; n++) { if (arts[n].getAttribute('data-id') == arr[i].id) { arts[n].getElementsByClassName('ms-icon')[0].className = 'ms-icon fa fa-close'; arts[n].getElementsByClassName('finished')[0].style.display = 'none'; arts[n].getElementsByClassName('star')[0].style.display = 'none'; } } } } } loadThing(); /*重置按钮*/ function resetContent() { var length = endTimes.length; textContent.value = ""; for (var i = 0; i < length; i++) { beginTimes[i].value = ""; endTimes[i].value = ""; } } reset.addEventListener('click', function(ev){ var ev = ev || event; ev.stopPropagation(); resetContent(); }, false); /*添加任务*/ add.addEventListener('click', function(ev){ var ev = ev || event; ev.stopPropagation(); var date = new Date(); var createTime, beginTime, contText, endTime, defY, defM, defD, msTime, em, bm, c, id = new Date().getTime(); if (textContent.value == "") { alert('输入不能为空'); return; } if (endTimes[0].value == "" || endTimes[1].value == "" || endTimes[2].value == "") { alert('结束时间不能留空'); return; } if (beginTimes[0].value == "") { defY = beginTimes[0].placeholder; } else { defY = beginTimes[0].value; } if (beginTimes[1].value == "") { defM = beginTimes[1].placeholder; } else { defM = beginTimes[1].value; } if (beginTimes[2].value == "") { defD = beginTimes[2].placeholder; } else { defD = beginTimes[2].value; } c = id - new Date(date.getFullYear() + '/' + (date.getMonth() + 1) + '/' + date.getDate()).getTime(); createTime = date.getFullYear() + '年' + (date.getMonth() + 1) + '月' + date.getDate() + '日'; endTime = { year: endTimes[0].value, month: endTimes[1].value, day: endTimes[2].value } em = new Date(endTime.year + '/' + endTime.month + '/' + endTime.day).getTime() + c; beginTime = { year: defY, month: defM, day: defD } bm = new Date(beginTime.year + '/' + beginTime.month + '/' + beginTime.day).getTime() + c; msTime = '任务有效期:' + beginTime.year + '年' + beginTime.month + '月' + beginTime.day + '日 至 ' + endTime.year + '年' + endTime.month + '月' + endTime.day + '日'; /*一个文章的整体数据*/ var contText = { text: textContent.value, createTime: createTime, beginTime: beginTime, endTime: endTime, star: false, finished: 0, msTime: msTime, id: id, bm: bm, em: em } data.push(contText); lcdata = JSON.stringify(data); localStorage.setItem('D', lcdata); createAriticle(contText.id, contText.text, contText.createTime, contText.msTime); resetContent(); }, false); })()
六,不足之处:
1,在输入日期的时候没有过滤掉非法日期,这里最好能用一个日历组件进行选择日期,能保证日期的准确性。否则任务的完成时间会出错,导致页面渲染错误。(组件正在开发中,后期会分享)
2,缺少弹窗提示,这里的操作动作很多,完全可以开发一个弹窗组件,方便用。体验比较好。(组件正在开发中,后期会分享)
3,创建后的任务不能更改任务内容是个缺陷。
demo分享到此结束,笔者有什么地方错误或者理解不到位的地方还请大家指出来。