附录4-项目ToDoList

目录

1  功能

2  结构与样式

3  JS部分

3.1  定义读取本地存储数据函数

3.2  定义保存本地存储数据函数

3.3  定义渲染页面函数

3.4  输入功能

3.5  删除功能

3.6  切换任务的状态


1  功能

在文本框中输入内容,然后按下回车,会将内容添加到正在进行中

如果头部的checkbox是被勾选的状态,该条就会到已经完成的下方

点击条目后面的圆按钮,会将该条删除

写入的内容在关闭浏览器后再次访问,之前写的内容不会消失

2  结构与样式

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="css/initialization.css">
    <link rel="stylesheet" href="css/index.css">
</head>
<body>
    <header>
        <div class="container">
            <span>ToDoList</span>
            <input type="text" placeholder="添加ToDo" maxlength="20">
        </div>
    </header>
    <section class="doing">
        <div class="container">
            <div class="doing_header">
                <h1>正在进行</h1>
                <div class="doing_num">0</div>
            </div>
            <div class="doing_content">
                <!-- <div class="doing_line">
                    <div class="left_color"></div>
                    <input type="checkbox">
                    <span>1</span>
                    <button>
                        <div></div>
                    </button>
                </div> -->
            </div>
        </div>
    </section>
    <section class="done">
        <div class="container">
            <div class="done_header">
                <h1>已经完成</h1>
                <div class="done_num">0</div>
            </div>
            <div class="done_content">
                <!-- <div class="done_line">
                    <div class="left_color"></div>
                    <input type="checkbox" checked="checked">
                    <span>1</span>
                    <button>
                        <div></div>
                    </button>
                </div> -->
            </div>
        </div>
    </section>
    
</body>
<script src="../jquery-3.6.1.min.js"></script>
<script src="js/index.js"></script>
</html>

css

body {
    // height:3000px;
    background-color: rgb(204,205,204);
    header {
        width: 100%;
        height:50px;
        background-color: rgb(48,49,48);
        .container {
            max-width:600px;
            margin:0 auto;
            span {
                float:left;
                color: #DDD;
                font-size:24px;
                line-height: 50px;
            }
            input {
                float: right;
                width:60%;
                height:24px;
                margin-top:12px;
                text-indent: 10px;
                border-radius: 5px;
                box-shadow: 0 1px 0 rgb(255 255 255 / 24%), 0 1px 6px rgb(0 0 0 / 45%) inset;
            }
        }
    }

    .doing {
        .container {
            max-width:600px;
            margin:0 auto;
            .doing_header {
                display: flex;
                justify-content: space-between;
                margin-top:20px;
                h1 {
                    display: inline-block;
                    font-size: 25px;
                    font-weight: bold;
                    color:rgb(0,0,0)
                }
                .doing_num {
                    width:30px;
                    height:20px;
                    color:rgb(102,102,126);
                    font-weight: bold;
                    text-align: center;
                    line-height: 20px;
                    font-size:14px;
                    border-radius: 10px;
                    background-color: rgb(230,230,250);
                }
            }
            .doing_content {
                width:100%;
                margin-top: 20px;
                .doing_line {
                    position: relative;
                    width: 100%;
                    height:32px;
                    border-radius: 5px;
                    background-color: rgb(255,255,255);
                    overflow: hidden;
                    margin-top: 10px;
                    .left_color {
                        display: inline-block;
                        width:5px;
                        height:100%;
                        background-color: rgb(98,154,156);
                    }
                    input {
                        position: absolute;
                        top:5px;
                        left:20px;
                        width:22px;
                        height:22px;
                    }
                    span {
                        position:absolute;
                        left:50px;
                        font-size:18px;
                        line-height: 32px;
                        color:rgb(0,0,0)
                    }
                    button {
                        position: absolute;
                        top:3px;
                        right:5px;
                        width:26px;
                        height:24px;
                        border:3px solid rgb(204,204,204);
                        border-radius: 50%;
                        background-color: transparent;
                        div {
                            position: absolute;
                            left: 50%;
                            top:50%;
                            transform: translate(-50%,-50%);
                            width:14px;
                            height:12px;
                            border-radius: 50%;
                            background-color: rgb(204,204,204);
                        }
                    }
                }
            }
        }
    }

    .done {
        .container {
            max-width:600px;
            margin:0 auto;
            .done_header {
                display: flex;
                justify-content: space-between;
                margin-top:20px;
                h1 {
                    display: inline-block;
                    font-size: 25px;
                    font-weight: bold;
                    color:rgb(0,0,0)
                }
                .done_num {
                    width:30px;
                    height:20px;
                    color:rgb(102,102,126);
                    font-weight: bold;
                    text-align: center;
                    line-height: 20px;
                    font-size:14px;
                    border-radius: 10px;
                    background-color: rgb(230,230,250);
                }
            }

            .done_content {
                width:100%;
                margin-top: 20px;
                .done_line {
                    position: relative;
                    width: 100%;
                    height:32px;
                    border-radius: 5px;
                    background-color: rgb(237,237,237);
                    overflow: hidden;
                    margin-top: 10px;
                    opacity: 0.5;

                    .left_color {
                        display: inline-block;
                        width:5px;
                        height:100%;
                        background-color: #999;
                        
                    }
                    input {
                        position: absolute;
                        top:5px;
                        left:20px;
                        width:22px;
                        height:22px;
                    }
                    span {
                        position:absolute;
                        left:50px;
                        font-size:18px;
                        line-height: 32px;
                        color:rgb(0,0,0)
                    }
                    button {
                        position: absolute;
                        top:3px;
                        right:5px;
                        width:26px;
                        height:24px;
                        border:3px solid rgb(204,204,204);
                        border-radius: 50%;
                        background-color: transparent;
                        div {
                            position: absolute;
                            left: 50%;
                            top:50%;
                            transform: translate(-50%,-50%);
                            width:14px;
                            height:12px;
                            border-radius: 50%;
                            background-color: rgb(204,204,204);
                        }
                    }
                }
            }
        }
    }
}

虽然打开的时候是这样的

还是要在早期把样式搞定,省的后面麻烦

3  JS部分

load()

function getDate() {
    var data = localStorage.getItem("todolist");
    if (data !== null) {
        return JSON.parse(data);
    } else {
        return [];
    }
}

function saveDate(data) {
    localStorage.setItem("todolist", JSON.stringify(data));
}

function load() {
    var data = getDate();
    $(".done_content,.doing_content").empty();
    var doingCount = 0;
    var doneCount = 0; 
    $.each(data, function(index, content) {
        if (content.done) {
            $(".done_content").prepend('<div class="done_line" index='+index+'><div class="left_color"></div><input type="checkbox" checked="checked"><span>'+content.content+'</span><button><div></div></button></div>');
            doneCount = doneCount + 1;
            }
        else {
            $(".doing_content").prepend('<div class="doing_line" index='+index+'><div class="left_color"></div><input type="checkbox"><span>'+content.content+'</span><button><div></div></button></div>');
            doingCount = doingCount + 1;
            }
        }
    )
    $('.doing_num').text(doingCount)
    $('.done_num').text(doneCount)
};

$('header .container input').on('keydown',function(e) {
    if (e.keyCode == 13) {
        if ($(this).val()) {
            data = getDate()
            data.push({content:$(this).val(),done:false})
            saveDate(data)
            $(this).val('')
            load()
        }
    }
})

$('.doing_content,.done_content').on('click','button',function() {
    data = getDate()
    data.splice($(this).parent()[0].getAttribute('index'),1)
    saveDate(data)
    load()
})

$('.doing_content,.done_content').on('click','input[type="checkbox"]',function() {
    data = getDate()
    data[$(this).parent()[0].getAttribute('index')].done = $(this).prop("checked")
    saveDate(data)
    load()
})

关闭页面数据仍然不消失应该用localStorage,如果使用sessionStorage关闭浏览器后数据会消失。

存储信息的方式是这样的,首先搞一个数组,里面放若干对象,对象的属性content是条目的内容,属性done的值为布尔值,如果为true就表示做完了,放在已经完成中,如果为false就表示没做完,放在正在进行中

本地存储只能储存字符串,所以会用到下面两个方法

  • JS变量 = JSON.parse(JSON字符串) 将JSON字符串转变为JS变量
  • JSON字符串 = JSON.stringify(JS变量) 将JS变量转变为JSON字符串

JSON不仅仅使用于本地存储,在与后端的交互中也比较常用

3.1  定义读取本地存储数据函数

先声明一个变量去拿键todolist的值,如果拿到了就将data转换为JS变量然后返回,如果拿不到就返回一个空数组

3.2  定义保存本地存储数据函数

将JS变量转换为字符串,然后存到键为todolist的对象中

3.3  定义渲染页面函数

  • 后面太长了就截不全了
  1. 首先读取存储好的todolist内容
  2. 将之前的正在进行的任务与完成的任务清空,因为我们后面要重新加载一遍,如果不清空就重复了
  3. 定义正在进行的任务数与已完成的任务数起始值为0
  4. 遍历读取到的数据,数据我们之前存储的形式是数组里面有若干个对象
    • 判断done属性的内容,如果为true就是已完成,生成已完成的元素到已完成中,然后已完成数量+1。这里后面的一堆HTML直接复制的HTML结构中的,加了两个属性,一个是index,给一个索引,让后面删和改的时候好处理,另一个是content,这个内容
    • 如果为False就是未完成,与已完成的样式除了CSS不同之外,已完成中的input有checked="checked",未完成中没有(不让其自动勾选)

定义完load()函数后,在开始就使用一遍load()函数,将过往存储的信息加载一遍

3.4  输入功能

使用键盘按下事件,如果按下了回车(keyCode == 13,按回车使用key的字符就不方便了(比如按下e键就写e),也不用特意记录,每次用的时候console.log(e.keyCode)就行了),如果按下回车的时候内容不为空就进行下面的操作,首先获取一遍本地存储的数据,然后再数据的最后的位置加入一条新数据,由于你在文本框中输入的内容都会放在正在进行中,所以done直接给false就行,然后保存数据,将input内容清空,然后加载数据

push()和下面将要提到的splice()都是JS远程数组的内置方法,详细使用方式可以看一下这个 10. 数组 Array_Suyuoa的博客-CSDN博客_js 数组中是否存在某个元素

3.5  删除功能

在这里一定要用on的selector参数绑定事件,只有这样才能给不存在的元素绑定事件

  • on绑定可以给未生成的元素绑定,前提是使用on的对象不能是新生成的

先读取,再删除,之后存,存完了加载

3.6  切换任务的状态

如果是已完成的任务点前面的checkbox会变成未完成,如果是未完成的任务点前面的checkbox会变成已完成

逻辑相似,先拿数据,再改数据,然后存数据,最后加载页面

prop()是jQuery中的获取固有属性值的方法,在这里面有介绍 6.jQuery常用属性操作_Suyuoa的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Suyuoa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值