核心功能:
- 添加任务(add按钮)
- 完成任务(mark按钮,完成后任务不可点击修改按钮)
- 修改任务(update按钮,修改任务期间不可点击完成和删除按钮)
- 删除任务(delete按钮)
HTNL部分代码
html
<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样式代码
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()
:作用是去掉字符全前后的空格
- 任务添加后,输入框中的内容清空
javascript
// 添加事件
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("")
:作用询问框
javascript
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()
操作中
javascript
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.previousElementSibling
target.style.textDecoration = "line-through"
target.style.color = "#a4b0be"
target.style.background = "#f1f2f6"
endCompleted = this.parentElement.parentElement//完成的事项
tbody.appendChild(endCompleted)
}
}
}
优化1:只用完成的待办事项才能删除
优化删除事件中的代码,设置只有完成的才能删除:
javascript
if(this.parentElement.previousElementSibling.style.textDecoration == "line-through"){//设置只有完成的才能删除
if(confirm("确定要删除吗?")){
tbody.removeChild(target)
}
} else {
alert("完成才能删除!!!请努力完成吧!!!")
}
优化2:完成的待办事项在最底部,新添加的任务在完成的上面
优化添加事件中的代码,设置新任务插入到完成事项的上面:
javascript
var fistCompleted = tbody.querySelector('tr td[style*="line-through"]')// 插入到tbody的开头(所有已完成事项的上方)
if(fistCompleted){
tbody.insertBefore(tr, fistCompleted.parentNode)
}else{
tbody.appendChild(tr)//将tr放置在tbody标签内
}
优化3:完成的事项不需要进行修改
优化完成事件中的代码,添加一个逻辑判断:
javascript
if(target.style.textDecoration=='line-through'){
var updateBtn = this.parentElement.querySelector(".update")
updateBtn.disabled = true
}
修改事件
- 由于修改按钮是任务添加后才有的操作,所以要写在
btn.onclick = function()
操作中 - 修改事项内容返回到输入框中,且添加按钮改为修改按钮,修改内容后,点击修改按钮,之后输入框内容清空,按钮变会添加按钮
javascript
var target_up//全局变量
var markBtn
var deleteBtn
var updates
btn.onclick = function(){
// 修改事件
// 第一步:回显
updates = document.querySelectorAll(".update")
for(var i=0;i<updates.length;i++){
updates[i].onclick = function(){//绑事件
target_up = this.parentElement.previousElementSibling
text.value = target_up.innerHTML
btn.value = 'update'
target_up.style.background = "#f1f2f6"
}
}
// 第二步:修改
if(btn.value == 'update'){//判断是添加还是修改按钮
target_up.innerHTML = text.value
text.value = ""
btn.value = "add"
target_up.style.background = "#fff"
return
}
}
优化:修改时,其他的操作按钮不能点击
javascript
markBtn = this.parentElement.querySelector(".mark");
deleteBtn = this.parentElement.querySelector(".delete");
markBtn.disabled = true;
deleteBtn.disabled = true;//上面四行代码作用是:修改时,这两个按钮不能点击
JavaScript完整代码
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 markBtn
var deleteBtn
var updates
btn.onclick = function(){ //绑事件,事件触发之后,才执行
// 第二步:修改
if(btn.value == 'update'){//判断是添加还是修改按钮
target_up.innerHTML = text.value
text.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.previousElementSibling
target.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.previousElementSibling
text.value = target_up.innerHTML
btn.value = 'update'
target_up.style.background = "#f1f2f6"
markBtn = this.parentElement.querySelector(".mark");
deleteBtn = this.parentElement.querySelector(".delete");
markBtn.disabled = true;
deleteBtn.disabled = true;//上面四行代码作用是:修改时,这两个按钮不能点击
}
}
}
}
