一. 需求
1. 可以添加事务
2. 可以删除事务
3. 可以标注完成了哪些事务,并且可以删除已经完成的事务。
二. 思路
1. 事务全部存储在一个数组中,data。
2. 基于这个 data 数组生成事务列表结构。
3. 事务状态(完成与否)的更改,也是先改data数组的内容,然后基于 data生成事务列表。
三. 核心功能
1. 添加事务:点击按钮给data数组增加一个对象元素。
let obj = { content:"abc", time:时间, ok:false }
content 内容来自输入框。time 就是发布的时间。ok 代表是否完成,默认事务都没完成。
2. 显示事务内容
每条事务都是 li,其主要结构示例如下:
<li>
<div class="check">
<input type="checkbox" name="" id="">
</div>
<div class="listNr">今天要去完成作业</div>
<div class="op">
<a href="javascript:void(0)">删除</a>
</div>
</li>
3. 删除事务:点击 “删除”的连接标签,就删除对应的data的元素值,再基于data更新显示的HTML。
4. 更改事务状态:修改data中,对应数据的 ok 值。
5. 删除完成了的事务:遍历data,删除ok为true的元素,再更新显示HTML。
四、关键代码
HTML:
<div class="todoList">
<div class="form">
<input type="text" class="input" id="myInput">
<button type="button" class="btn" id="btn">添加</button>
<button type="button" class="btn" id="del">删除完成的list</button>
</div>
<ul class="list" id="myUl">
</ul>
</div>
主要CSS:
.todoList{
width: 800px;
margin-left: auto;
margin-right: auto;
background: #eee;
padding: 30px;
}
.input{
height: 40px;
line-height: 40px;
font-size: 16px;
padding-left: 20px;
padding-right: 20px;
width: 400px;
border:1px #333 solid;
}
.btn{
height: 42px;
width: 100px;
background: #f90;
color: #fff;
cursor: pointer;
}
.btn:hover{
background: #f30;
}
.list li{
display: flex;
height: 50px;
line-height: 50px;
border-bottom: 1px #ccc dashed;
justify-content: flex-start;
}
.list li .listNr{
flex: 1;
padding-left: 10px;
padding-right: 20px;
}
.list li.true{
background: #bef1cc;
}
.list li.false{
background: #f6c7c7;
}
关键JS:
let dataArr = [];
let myInput = document.getElementById("myInput");
let btn = document.getElementById("btn");
let myUl = document.getElementById("myUl");
let del = document.getElementById("del");
showContent();
// 添加内容
btn.addEventListener("click",function(){
let v = myInput.value;
let time = new Date();
let myTime = `${time.getFullYear()}-${time.getMonth()+1}-${time.getDate()}`;
let obj = {
content:v,
time:myTime,
ok:false
}
dataArr.push(obj);
myInput.value = ""; // 清空 input 的内容
showContent();
});
// 删除完成的 list
del.addEventListener("click",function(){
dataArr = dataArr.filter(v=>{ // 保留 ok状态为false的元素。
return v.ok == false;
});
showContent();
});
// 改变checkbox
function changeBox(tag){
// 更改对应数组元素的ok值
let li = tag.parentNode.parentNode;
let liIndex = Number(li.getAttribute("index").trim());
dataArr[liIndex].ok = tag.checked ;
showContent();
}
// 显示内容函数
function showContent(){
let html = ""; // 清空 ul
dataArr.forEach((v,i)=>{
let li = `
<li time="v.time" class="${v.ok}" index="${i}">
<div class="check">
<input onchange="changeBox(this)" type="checkbox"
${ v.ok? "checked":""} >
</div>
<div class="listNr">${v.content}</div>
<div class="op">
<a href="javascript:void(0)" class="del">删除</a>
</div>
</li>
`;
html += li;
});
myUl.innerHTML = html ; // 一次写入,避免多次HTML DOM操作。
}
// 点击“删除”连接,删除内容。
// 这里使用了事件委托
myUl.addEventListener("click",function(event){
let tag = event.target ;
if( tag.className == "del" ){
console.info("删除");
let li = tag.parentNode.parentNode;
let liIndex = Number(li.getAttribute("index").trim()); // 获取索引
// 方式一:
// 从数组里删除对应元素
// dataArr.splice(liIndex,1);
// 方式二: filter 不会破坏原数组。
dataArr= dataArr.filter((v,i)=>{
console.info( i != liIndex );
return i != liIndex ;
});
showContent(); // 显示内容
}
});
完工。