JavaScript、css/html实现代办事项列表

css样式
html{
    background-color: #CCCCCC;
}
body{
    margin: 0px;
    padding: 0px;
}
.tops {
    width: 100%;
    height: 50px;
    background-color: rgba(47, 47, 47, 0.98);
}
label{
    float: left;
    width: 100px;
    line-height: 50px;
    color: #ddd;
    font-size: 24px;
    cursor: pointer;
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
input[type="text"] {
    width: 60%;
    height: 24px;
    margin-top: 12px;
    text-indent: 10px;
    border-radius: 5px;
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.24),
      0 1px 6px rgba(0, 0, 0, 0.45) inset;
    border: none;
    float: right;
}
.topInfo, .infoContent{
    width: 50%;
    margin: auto;
}
.undone,.done{
    margin-top: 20px;
    font-size: 25px;
    font-weight: 900;
    position: relative;
}
.info>span{
    position: absolute;
    top: 5px;
    right: 5px;
    display: inline-block;
    padding: 0 5px;
    height: 20px;
    border-radius: 20px;
    background: #E6E6FA;
    line-height: 22px;
    text-align: center;
    color: #666;
    font-size: 14px;
}
ul{
    list-style: none;
    font-size: 14px;
    font-weight: 400;
    margin: 0;
    padding: 0;
    margin-top: 10px;
}
li{
    height: 32px;
    line-height: 32px;
    background: #fff;
    margin-bottom: 10px;
    padding: 0 45px;
    overflow: hidden;
    border-radius: 3px;
    border-left: 5px solid #629A9C;
    box-shadow: 0 1px 2px rgba(0,0,0,0.07);
    position: relative;
}
 
li.doneLi{
    border-left: 5px solid #999;
    opacity: 0.5;
}
.close{
    display: inline-block;
    position: absolute;
    right: 20px;
    top:4px;
    border-radius: 10px;
}
input.changeInput{
    width: 300px;
    display: none;
    position: absolute;
}
html

<div class="tops">
    
    <div class="topInfo">
        <label>ToDoListlabel>
        
        <input type="text" name="addInfo" class="addInfo" placeholder="添加ToDo"/>
    div>
div>

<div class="infoContent">
    
    <div class="undone">
        <div class="info">
            正在进行
            <span>0span>
        div>
    div>
    
    <div class="done">
        <div class="info">
            已经完成
            <span>0span>
        div>
    div>
div>

<input type="text" class="changeInput">
js
// arr 数组列表
// addInfo 添加信息
// undone 未完成
// done 完成
// undoneSpan 未完成span标签内容
// doneSpan 完成span标签内容
// undoneUl 未完成ul列表
// doneUl 完成ul列表
// changeInput 改变input文本框内容
var arr,addInfo,undone,done,undoneSpan,doneSpan,undoneUl,doneUl,changeInput;

// 初始化执行函数
init();
function init(){
    // 获取input输入框类名addInfo标签元素
    addInfo=document.querySelector(".addInfo");
    // 获取input输入框类名changeInput标签元素
    changeInput=document.querySelector(".changeInput");
    // 获取类名undone标签元素,表示含义未完成
    undone=document.querySelector(".undone");
    // 获取类名done标签元素,表示含义完成
    done=document.querySelector(".done");
    // 获取完成和未完成下面的大容器下面的span标签元素
    undoneSpan=document.querySelector(".undone span");
    doneSpan=document.querySelector(".done span");
    // 从localStorage获取todoList,如果有就转换为对象,如果没有就创建一个数组
    arr=localStorage.todoList ? JSON.parse(localStorage.todoList) : [];
    // 执行dataSave函数,用于存储数据,拆分数据
    // 重新刷新数据
    dataSave();
    // 给文档添加按键事件
    document.addEventListener("keyup",keyHandler);
}

// TODO  敲回车添加数据,按键事件函数
function keyHandler(e){
    // 如果按键不是回车就return不进入继续向后执行
    if(e.keyCode!==13) return;
    // 当添加数据输入框内容长度为0时,不再向后执行
    if(addInfo.value.trim().length===0) return;
    // 获取localStorage存储的todoList;
    arr=JSON.parse(localStorage.todoList);
    // 创建一个新对象,将当前的文本框中输入的内容放在这个对象的info中,设置finish默认为false
    arr.push({finish:false,info:addInfo.value});
    // 执行dataSave函数,重新刷新数据
    dataSave();
    // 清空文本框内容
    addInfo.value="";
}   

// TODO  完成数据整理并且存储,完成数据的分类并且计算总数
function dataSave(){
    // 将数组转换为字符串存储在localStorage中
    localStorage.todoList=JSON.stringify(arr);
    // 数组进行过滤,将未完成是false值返回出去放在undoneList数组中
    var undoneList=arr.filter(item=>{
        return !item.finish;
    })
    // 数组进行过滤,将完成是true值返回出去放在doneList数组中
    var doneList=arr.filter(item=>{
        return item.finish;
    })
    // 每个项的列表数量。
    // 将未完成的数组数量放在undoneSpan中
    // 将完成的数组数量放在doneSpan中
    undoneSpan.textContent=undoneList.length;
    doneSpan.textContent=doneList.length;
    // 如果未完成的任务ul列表中,已经创建了就将它删除,并且设置为null
    // 保证每次数据都是最新的一个
    if(undoneUl){
        undoneUl.remove();
        undoneUl=null;
    }
    // 如果完成的任务ul列表中,已经创建了就将它删除,并且设置为null
    if(doneUl){
        doneUl.remove();
        doneUl=null;
    }
    // 通过执行createUl函数根据undoneList创建ul,并且放在undone容器中
    // 并且返回ul赋值给undoneUl全局变量,上面的判断就是ul任务列表是否存在
    undoneUl=createUl(undoneList,undone);
    // 通过执行createUl函数根据doneList创建ul,并且放在done容器中
    // 并且返回ul赋值给doneUl全局变量,上面的判断就是ul任务列表是否存在
    doneUl=createUl(doneList,done);
}
// 注意:
// 引用关系的参数不可以删除不可以设置为null
// 引用的参数如果牵扯到创建,必须返回设置
// 所以在创建ul列表函数中,将结果使用return返回给全局变量

// TODO 创建UL列表
// 将undoneList、doneList和undone、done作为参数带入函数中
function createUl(list,parent){
    // 创建ul
    var ul=document.createElement("ul");
    // 根据数组遍历创建li
    for(var i=0;i<list.length;i++){
        // 创建li标签元素
        var li=document.createElement("li");
        // 将选中的元素,给li标签元素添加类名,设置css样式
        if(list[i].finish) li.className="doneLi";
        // 创建input标签元素
        var ck=document.createElement("input");
        // 设置类型为多选框
        ck.type="checkbox";
        // 将每一行的数据对象添加到ck自定义属性data上,引用地址都相同
        ck.data=list[i];
        // 根据数据中finish值设置多选框是否被选中
        ck.checked=list[i].finish;
        // 给多选框添加点击事件
        ck.addEventListener("click",clickHandler);
        // 将创建好的多选框放入到li标签元素中
        li.appendChild(ck);
        // 创建span标签元素
        var span=document.createElement("span");
        // 给span元素中放入内容的数据是info也就是用户输入需要添加的内容
        span.textContent=list[i].info;
        // 设置文本不能被选中
        span.style.userSelect="none";
        // 将span放入li标签元素中
        li.appendChild(span);
        // 将每一行的数据对象添加到span自定义属性data上
        span.data=list[i];
        // 给span添加鼠标双击事件,去改变文本框里面的内容
        span.addEventListener("dblclick",changeLiTextHandler);
        // 创建按钮
        var bn=document.createElement("button");
        // 按钮的内容是一个x也就是删除的意思
        bn.innerHTML="x";
        // 设置按钮的样式
        bn.className="close";
        // 将每一行的数据对象添加到bn自定义属性data上
        bn.data=list[i];
        // 添加按钮点击事件
        bn.addEventListener("click",removeClickHandler);
        // 将bn放在li标签元素中
        li.appendChild(bn);
        // 将li放在ul标签元素中
        ul.appendChild(li);
    }
    // 将ul放在指定的父容器中
    parent.appendChild(ul);
    // 返回创建好的ul
    return ul;
}

// TODO 删除列表
function removeClickHandler(e){
    // 在列表中去查找点击按钮需要删除的一条数据
    // bn.data有每一行数据对象
    var index=arr.indexOf(this.data);
    // 大于-1也就是找到了,进行删除
    if(index>-1) arr.splice(index,1);
    // 执行dataSave函数,重新刷新数据
    dataSave();
}

// TODO 修改事项
function clickHandler(e){
    // 修改了this.data.finish,就当于修改了list[i]里面的finish
    // 根据点击改变多选框的状态,true或者false去改变任务列表是完成还是未完成
    this.data.finish=this.checked;
    // 执行dataSave函数,重新刷新数据
    dataSave();
}

// 鼠标双击事件,去改变文本框里面的内容
function changeLiTextHandler(e){
    // input文本框双击时显示
    changeInput.style.display="block";
    // getBoundingClientRect()
    // 获取页面中input标签元素的左,上,右和下分别相对浏览器视窗的位置
    var rect=this.getBoundingClientRect();
    // 设置定位距离左边位置
    changeInput.style.left=rect.x+"px";
    // 设置定位距离顶部位置
    changeInput.style.top=rect.y-16+"px";
    // 获取span属性data数据
    // 所有data和list[i]对象引用地址相同
    changeInput.data=this.data;
    // 双击文本框时聚焦
    changeInput.focus();
    // 添加失焦事件
    changeInput.addEventListener("blur",blurHandler);
}

// 失焦事件函数
function blurHandler(e){
    // 鼠标离开失焦时,将现在文本框里面的内容赋给之前的内容进行修改
    this.data.info=this.value;
    // 然后进行清空隐藏
    this,data=null;
    this.value="";
    this.style.display="none";
    // 执行dataSave函数,重新刷新数据
    dataSave();
}

你可能感兴趣的:(JavaScript、css/html实现代办事项列表)