zoukankan      html  css  js  c++  java
  • 案例:toDoList

    具体功能可参考网站:http://www.todolist.cn/

    实现功能如下:

    1. 文本框里面输入内容,按下回车,就可以生成待办事项。

    2. 点击待办事项的复选框,就可以把当前数据添加到已完成事项里面。

    3. 点击已完成事项的复选框,就可以把当前数据添加到待办事项里面。

    4. 但是本页面内容刷新页面不会丢失。

    具体的实现思路如下:

    1. 存储数据功能:

    ① 刷新页面不会丢失数据,因此需要用到本地存储localStorage

    ② 核心思路:不管按下回车,还是点击复选框,都是把本地存储的数据加载到页面中,这样保证刷新关闭页面时不会丢失数据

    ③ 存储的数据格式:var todolist = [{title: 'xxx', done: false}]

    ④ 注意点1:本地存储localStorage里面只能存储字符串格式,因此需要把对象转换为字符串,使用JSON.stringify(data)

    ⑤ 注意点2:获取本地存储数据,需要把里面的字符串转换为对象格式才能使用里面的数据,使用JSON.parse()

    2. 按下回车把新数据添加到本地存储里面:

    ① 切记:页面中的数据,都要从本地存储里面获取,这样刷新页面才不会丢失数据,所以要先把数据保存到本地存储里面,再进行后续的操作

    ② 利用事件对象.keyCode判断用户按下回车键(13)

    ③ 声明一个数组,保存数据

    ④ 先要读取本地存储原来的数据(声明函数getData()),放到这个数组里面

    ⑤ 之后把最新从表单获取过来的数据,追加到数据里面

    ⑥ 最后把数组存储给本地存储(声明函数saveData())

    3. 本地存储数据渲染加载到页面:

    ① 因为后面也会经常渲染加载操作,所以声明一个函数load,方便后面调用

    ② 先要读取本地存储数据(数据不要忘记转换为对象格式)

    ③ 之后遍历这个数据($.each()),有几条数据,就生成几个小li添加到ol里面

    ④ 每次渲染之前,先要把原先里面ol的内容清空,然后渲染加载最新的数据

    4. 删除操作:

    ① 点击里面的a链接,不是删除的li,而是删除本地存储对应的数据

    ② 核心原理:先获取本地存储数据,删除对应的数据,保存给本地存储,重新渲染列表li

    ③ 可以给链接自定义属性记录当前的索引号

    ④ 根据这个索引号删除相关的数据,使用数组的splice(i, 1)方法

    ⑤ 存储修改后的数据,然后存储给本地存储

    ⑥ 重新渲染加载数据列表

    ⑦ 因为a是动态创建的,所以必须要使用on()方法绑定事件

    注意,这里只能使用自定义索引号,因为jQuery提供的获取索引号的方法只能是兄弟元素之间才有连续的索引号,而本例中需要删除的几个a链接并不是兄弟关系。

    5. 正在进行和已完成选项操作:

    ① 当点击了小的复选框,修改本地存储数据,再重新渲染数据列表

    ② 点击之后,获取本地存储数据

    ③ 修改对应数据属性done为当前复选框的checked状态

    ④ 之后保存数据到本地存储

    ⑤ 重新渲染加载数据列表

    ⑥ load加载函数里面,新增一个条件,如果当前数据的done为true就是已经完成的,就把列表渲染加载到ul里面

    ⑦ 如果当前数据的done为false,则是待办事件,就把列表渲染加载到ol里面

    6. 统计正在进行个数和已经完成个数:

    ① 在load函数里面操作

    ② 声明2个变量:todoCount为待办个数,doneCount为已完成个数

    ③ 当进行遍历本地存储数据的时候,如果数据done为false,则todoCount++,否则doneCount++

    ④ 最后修改相应的元素的text()

    <!-- 页面布局 -->
    <body>
        <header>
            <section>
                <label for="title">ToDoList</label>
                <input type="text" id="title" name="title" placeholder="添加ToDo" required="required" autocomplete="off" />
            </section>
        </header>
        <section>
            <h2>正在进行 <span id="todocount"></span></h2>
            <ol id="todolist" class="demo-box">
    
            </ol>
            <h2>已经完成 <span id="donecount"></span></h2>
            <ul id="donelist">
            </ul>
        </section>
        <footer>
            Copyright © 2014 todolist.cn
        </footer>
    </body>
    /* CSS样式 */
    body {
        margin: 0;
        padding: 0;
        font-size: 16px;
        background: #CDCDCD;
    }
    header {
        height: 50px;
        background: #333;
        background: rgba(47, 47, 47, 0.98);
    }
    section {
        margin: 0 auto;
    }
    label {
        float: left;
        width: 100px;
        line-height: 50px;
        color: #DDD;
        font-size: 24px;
        cursor: pointer;
        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
    }
    header input {
        float: right;
        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
    }
    input:focus {
        outline-width: 0
    }
    h2 {
        position: relative;
    }
    span {
        position: absolute;
        top: 2px;
        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;
    }
    ol,
    ul {
        padding: 0;
        list-style: none;
    }
    li input {
        position: absolute;
        top: 2px;
        left: 10px;
        width: 22px;
        height: 22px;
        cursor: pointer;
    }
    p {
        margin: 0;
    }
    li p input {
        top: 3px;
        left: 40px;
        width: 70%;
        height: 20px;
        line-height: 14px;
        text-indent: 5px;
        font-size: 14px;
    }
    li {
        height: 32px;
        line-height: 32px;
        background: #fff;
        position: relative;
        margin-bottom: 10px;
        padding: 0 45px;
        border-radius: 3px;
        border-left: 5px solid #629A9C;
        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07);
    }
    ol li {
        cursor: move;
    }
    ul li {
        border-left: 5px solid #999;
        opacity: 0.5;
    }
    li a {
        position: absolute;
        top: 2px;
        right: 5px;
        display: inline-block;
        width: 14px;
        height: 12px;
        border-radius: 14px;
        border: 6px double #FFF;
        background: #CCC;
        line-height: 14px;
        text-align: center;
        color: #FFF;
        font-weight: bold;
        font-size: 14px;
        cursor: pointer;
    }
    footer {
        color: #666;
        font-size: 14px;
        text-align: center;
    }
    footer a {
        color: #666;
        text-decoration: none;
        color: #999;
    }
    @media screen and (max-device- 620px) {
        section {
            width: 96%;
            padding: 0 2%;
        }
    }
    @media screen and (min- 620px) {
        section {
            width: 600px;
            padding: 0 10px;
        }
    }

    出现一个bug:页面加载时需要调用一次load()函数将数据渲染到页面上。

    当添加一条数据后,又需要调用一次load()函数,数据就会重复渲染到页面上了

    解决方案:每次渲染之前,需要先把内容全部清空,然后渲染加载最新的数据

    $(function() {
        // alert(11);
        // 1. 按下回车 把完整数据 存储到本地存储里面
        // 存储的数据格式  var todolist = [{title: "xxx", done: false}]
        load();
        $("#title").on("keydown", function(event) {
            if (event.keyCode === 13) {
                if ($(this).val() === "") {
                    alert("请输入您要的操作");
                } else {
                    // 先读取本地存储原来的数据
                    var local = getData();
                    // console.log(local);
                    // 把local数组进行更新数据 把最新的数据追加给local数组
                    local.push({ title: $(this).val(), done: false });
                    // 把这个数组local 存储给本地存储
                    saveData(local);
                    // 2. toDoList 本地存储数据渲染加载到页面
                    load();
                    $(this).val("");
                }
            }
        });
        // 3. toDoList 删除操作
        $("ol, ul").on("click", "a", function() {
            // alert(11);
            // 先获取本地存储
            var data = getData();
            console.log(data);
            // 修改数据
            var index = $(this).attr("id");
            console.log(index);
            data.splice(index, 1);
            // 保存到本地存储
            saveData(data);
            // 重新渲染页面
            load();
        });
        // 4. toDoList 正在进行和已完成选项操作
        $("ol, ul").on("click", "input", function() {
            // alert(11);
            // 先获取本地存储的数据
            var data = getData();
            // 修改数据,注意,此时不需要再给复选框添加自定义索引号,只需要将它的兄弟a标签的自定义索引号拿过来用即可
            var index = $(this).siblings("a").attr("id");
            console.log(index);
            // data[?].done = ?
            data[index].done = $(this).prop("checked");
            console.log(data);
    
            // 保存到本地存储
            saveData(data);
            // 重新渲染页面
            load();
        });
        // 读取本地存储的数据 
        function getData() {
            var data = localStorage.getItem("todolist");
            if (data !== null) {
                // 本地存储里面的数据是字符串格式的 但是我们需要的是对象格式的
                return JSON.parse(data);
            } else {
                return [];
            }
        }
        // 保存本地存储数据
        function saveData(data) {
            localStorage.setItem("todolist", JSON.stringify(data));
        }
        // 渲染加载数据
        function load() {
            // 读取本地存储的数据
            var data = getData();
            console.log(data);
            // 遍历之前先要清空ol里面的元素内容
            $("ol, ul").empty();
            var todoCount = 0; // 正在进行的个数
            var doneCount = 0; // 已经完成的个数
            // 遍历这个数据
            $.each(data, function(i, n) {
                // console.log(n);
                if (n.done) {
                    $("ul").prepend("<li><input type='checkbox' checked='checked' > <p>" + n.title + "</p> <a href='javascript:;' id=" + i + " ></a></li>");
                    doneCount++;
                } else {
                    $("ol").prepend("<li><input type='checkbox' > <p>" + n.title + "</p> <a href='javascript:;' id=" + i + " ></a></li>");
                    todoCount++;
                }
            });
            $("#todocount").text(todoCount);
            $("#donecount").text(doneCount);
        }
    })
  • 相关阅读:
    2015上阅读计划
    《梦断代码》读书笔记 第2篇
    四则运算3
    求数组中最大子数组的和(一维)
    四则运算2—单元测试
    四则运算2
    《梦断代码》读书笔记 第1篇
    四组运算2(思路)
    四则运算1
    读书笔记
  • 原文地址:https://www.cnblogs.com/zcy9838/p/13021996.html
Copyright © 2011-2022 走看看