一,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分享到此结束,笔者有什么地方错误或者理解不到位的地方还请大家指出来。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。