使用JavaScript实现一个代办事项的小案例
核心功能:
- 添加任务(add按钮)
- 完成任务(mark按钮,完成后任务不可点击修改按钮)
- 修改任务(update按钮,修改任务期间不可点击完成和删除按钮)
- 删除任务(delete按钮)
HTNL部分代码
<body><div class="container"><!-- 输入框 --><form action="" class="form"><input type="text" class="text"><input type="button" value="add" class="btn"></form><!-- 内容区 --><table border="1" class="content"><thead><tr><th class="item-oper">代办事项</th><th id="operate" class="item-oper">操作</th></tr></thead><tbody><!-- 使用JavaScript生成任务列表 --></tbody></table></div>
</body>
- 输入框:是进行添加任务
- 内容区:是添加完任务后,通过JavaScript生成任务列表,对列表进行其它的操作
CSS样式代码
*{margin: 0;padding: 0;font-family: '怒放字体';border-radius: 2px;
}
@font-face {font-family: '怒放字体';src: url(../font/GongFanNuFangTi\(TaoBaoSouGongFanZiKuKeMaiDanZiShouQuan\)-2.ttf);
}.container{width: 400px;margin: 200px auto 0;
}/* 输入框 */
.form{display: flex;
}
.text{width: 360px;outline: none; /* 外轮廓去掉 */border: solid 1px;padding: 3px;
}
.btn{width: 40px;height: 26px;border: solid 1px;background: #ace3f4;
}/* 内容区 */
.content{margin-top: 15px;width: 100%;
}
.item-oper{text-align: center;border: black solid 1px;border-radius: 2px;background: #ace3f4;
}
#operate{width: 150px;
}
td{font-size: 14px;/* text-decoration: line-through; */
}
tr td:nth-child(2){text-align: center;padding: 2px 3px;
}
tr td:nth-child(2) input{border-width: 1px;margin: 0 2px;
}
通过HTML和CSS,简易的代办事项雏形已完成:
现在通过JavaScript来进行事件绑定,实现任务的添加、修改、删除、完成。
JavaScript代码
添加事件
- 添加事件要创建表格:第一个单元格放置添加内容,第二个单元格放置内容操作按钮,将单元格放置在tbody标签内
- 输入框中的字符串前后空格去掉,且不能添加空内容
trim()
:作用是去掉字符全前后的空格
- 任务添加后,输入框中的内容清空
// 添加事件
var btn = document.querySelector(".btn")
var text = document.querySelector(".text")
var tbody = document.querySelector("tbody")btn.onclick = function(){ //绑事件,事件触发之后,才执行if(text.value.trim()!=""){//如果输入不为空执行下面操作// 添加表格标签var tr = document.createElement("tr")//创建tr标签var td1 = document.createElement("td")//创建td标签var td2 = document.createElement("td")//创建td标签td1.innerHTML = text.value.trim()//第一个单元格赋输入的内容 trim()作用是去掉空格td2.innerHTML = '<input type="button" value="mark" class="mark">'+'<input type="button" value="delete" class="delete">'+'<input type="button" value="update" class="update"></input>'//第二个单元格赋按钮tr.appendChild(td1)tr.appendChild(td2)//将两个td标签放置在tr标签内tbody.appendChild(tr)//将tr放置在tbody标签内text.value = ""//添加后,输入框内容清空}
}
删除事件
- 由于删除按钮是任务添加后才有的操作,所以要写在
btn.onclick = function()
操作中 - 找到要删除的内容,询问是否确定要删除,防止误点删除按钮的问题
confirm("")
:作用询问框
btn.onclick = function(){// 删除事件var deletes = document.querySelectorAll(".delete")for(var i=0;i<deletes.length;i++){deletes[i].onclick = function(){//绑事件var target = this.parentElement.parentElement//找要删除的标签if(confirm("确定要删除吗?")){tbody.removeChild(target)}}}
}
完成事件
- 由于完成按钮是任务添加后才有的操作,所以要写在
btn.onclick = function()
操作中
var endCompleted//完成的事项btn.onclick = function(){// 完成事件var marks = document.querySelectorAll(".mark")for(var i=0;i<marks.length;i++){marks[i].onclick = function(){//绑事件var target = this.parentElement.previousElementSiblingtarget.style.textDecoration = "line-through"target.style.color = "#a4b0be"target.style.background = "#f1f2f6"endCompleted = this.parentElement.parentElement//完成的事项tbody.appendChild(endCompleted)}}
}
优化1:只用完成的待办事项才能删除
优化删除事件中的代码,设置只有完成的才能删除:
if(this.parentElement.previousElementSibling.style.textDecoration == "line-through"){//设置只有完成的才能删除if(confirm("确定要删除吗?")){tbody.removeChild(target)}} else {alert("完成才能删除!!!请努力完成吧!!!")}
优化2:完成的待办事项在最底部,新添加的任务在完成的上面
优化添加事件中的代码,设置新任务插入到完成事项的上面:
var fistCompleted = tbody.querySelector('tr td[style*="line-through"]')// 插入到tbody的开头(所有已完成事项的上方)
if(fistCompleted){tbody.insertBefore(tr, fistCompleted.parentNode)
}else{tbody.appendChild(tr)//将tr放置在tbody标签内
}
优化3:完成的事项不需要进行修改
优化完成事件中的代码,添加一个逻辑判断:
if(target.style.textDecoration=='line-through'){var updateBtn = this.parentElement.querySelector(".update")updateBtn.disabled = true
}
修改事件
- 由于修改按钮是任务添加后才有的操作,所以要写在
btn.onclick = function()
操作中 - 修改事项内容返回到输入框中,且添加按钮改为修改按钮,修改内容后,点击修改按钮,之后输入框内容清空,按钮变会添加按钮
var target_up//全局变量
var markBtn
var deleteBtn
var updatesbtn.onclick = function(){// 修改事件// 第一步:回显updates = document.querySelectorAll(".update")for(var i=0;i<updates.length;i++){updates[i].onclick = function(){//绑事件target_up = this.parentElement.previousElementSiblingtext.value = target_up.innerHTMLbtn.value = 'update'target_up.style.background = "#f1f2f6"} }// 第二步:修改if(btn.value == 'update'){//判断是添加还是修改按钮target_up.innerHTML = text.valuetext.value = ""btn.value = "add"target_up.style.background = "#fff"return}
}
优化:修改时,其他的操作按钮不能点击
markBtn = this.parentElement.querySelector(".mark");
deleteBtn = this.parentElement.querySelector(".delete");
markBtn.disabled = true;
deleteBtn.disabled = true;//上面四行代码作用是:修改时,这两个按钮不能点击
JavaScript完整代码
window.onload = function() {// 添加事件var btn = document.querySelector(".btn")var text = document.querySelector(".text")var tbody = document.querySelector("tbody")var endCompleted//完成的事项var target_up//全局变量var markBtnvar deleteBtnvar updatesbtn.onclick = function(){ //绑事件,事件触发之后,才执行// 第二步:修改if(btn.value == 'update'){//判断是添加还是修改按钮target_up.innerHTML = text.valuetext.value = ""btn.value = "add"target_up.style.background = "#fff"markBtn.disabled = false;deleteBtn.disabled = false;//回复按钮return}if(text.value.trim()!=""){//如果输入不为空执行下面操作// 添加表格标签var tr = document.createElement("tr")//创建tr标签var td1 = document.createElement("td")//创建td标签var td2 = document.createElement("td")//创建td标签td1.innerHTML = text.value.trim()//第一个单元格赋输入的内容 trim()作用是去掉空格td2.innerHTML = '<input type="button" value="mark" class="mark">'+'<input type="button" value="delete" class="delete">'+'<input type="button" value="update" class="update"></input>'//第二个单元格赋按钮tr.appendChild(td1)tr.appendChild(td2)//将两个td标签放置在tr标签内var fistCompleted = tbody.querySelector('tr td[style*="line-through"]')// 插入到tbody的开头(所有已完成事项的上方)if(fistCompleted){tbody.insertBefore(tr, fistCompleted.parentNode)}else{tbody.appendChild(tr)//将tr放置在tbody标签内}text.value = ""//添加后,输入框内容清空}// 删除事件var deletes = document.querySelectorAll(".delete")for(var i=0;i<deletes.length;i++){deletes[i].onclick = function(){//绑事件var target = this.parentElement.parentElement//找要删除的标签if(this.parentElement.previousElementSibling.style.textDecoration == "line-through"){//设置只有完成的才能删除if(confirm("确定要删除吗?")){tbody.removeChild(target)}} else {alert("完成才能删除!!!请努力完成吧!!!")}}}// 完成事件var marks = document.querySelectorAll(".mark")for(var i=0;i<marks.length;i++){marks[i].onclick = function(){//绑事件var target = this.parentElement.previousElementSiblingtarget.style.textDecoration = "line-through"target.style.color = "#a4b0be"target.style.background = "#f1f2f6"endCompleted = this.parentElement.parentElement//完成的事项tbody.appendChild(endCompleted)if(target.style.textDecoration=='line-through'){var updateBtn = this.parentElement.querySelector(".update")updateBtn.disabled = true}}}// 修改事件// 第一步:回显updates = document.querySelectorAll(".update")for(var i=0;i<updates.length;i++){updates[i].onclick = function(){//绑事件target_up = this.parentElement.previousElementSiblingtext.value = target_up.innerHTMLbtn.value = 'update'target_up.style.background = "#f1f2f6"markBtn = this.parentElement.querySelector(".mark");deleteBtn = this.parentElement.querySelector(".delete");markBtn.disabled = true;deleteBtn.disabled = true;//上面四行代码作用是:修改时,这两个按钮不能点击} }}
}