todolist 包含本地存储知识

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>todolist_again</title>
    <script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        .fat {
            width: 500px;
            height: 800px;
            margin: 50px auto;
        }
        h1 {
            font-size: 38px;
            color: goldenrod;
            display: inline;
            margin-right: 40px;
            /* vertical-align: middle; */
        }
        .todoinput {
            width: 300px;
            height: 50px;
            line-height: 50px;
            border-radius: 10px;
            border: 2px solid rgb(245, 161, 102);
            font-size: 28px;
            text-align: center;
            outline-style: none;
            /* outline-color: brown; */
            /* input获得焦点时,默认会出现一个蓝色外边框,设置outline属性,或者border属性,能清除该默认样式 */
        }
        h3 {
            font-size: 34px;
            float: left;
        }
        #todocount,#donecount {
            width: 30px;
            height: 40px;
            line-height: 40px;
            border-radius: 10px;
            background: goldenrod;
            display: block;
            float: right;
            margin-top: 2px;
            text-align: center;
            color:white;
        }
        .clearfix:after {
            display: block;
            height: 0;
            line-height: 0;
            content: "";
            clear: both;
            visibility: hidden;
        }
        .clearfix {
            zoom: 1;   
        }
        .main {
            margin-top: 40px;
            margin-bottom:  20px;
        }
        li {
            width: 100%;
            background: olive;
            border-radius: 7px;
            height: 30px;
            line-height: 30px;
            margin-top: 10px;
            list-style: none;
            position: relative;
        }
        #donelist li{
            opacity: .6;
        }
        .check {
            width: 21px;
            height: 21px;
            margin-left: 10px;
            vertical-align: middle;
        }
        .content {
            color: white;
            margin-left: 28px;
            font-family: '宋体';
            font-size: 18px;
        }
        .del {
            width: 16px;
            height: 16px;
            border-radius: 7px;
            background: orangered;
            display: block;
            position: absolute;
            right: 8px;
            top: 15px;
            margin-top: -8px;
        }

    </style>
</head>
<body>
    <section class="fat">
            <section>
                    <!-- οnfοcus="this.placeholder=''" οnblur="this.placeholder='添加todo'" -->
                <h1>todolist</h1><input type="text" placeholder="添加todo" class="todoinput">
            </section>
            
            <section class="main">
                <section class="clearfix">
                    <h3>正在进行</h3><span id="todocount"></span>
                </section>
                <ol id="todolist">
                    <!-- <li>
                        <input type="checkbox" class="check"><span class="content">了jog了</span><a href="###" class="del"></a>
                    </li> -->
                </ol>
            </section>
        
            <section class="main">
                <section class="clearfix">
                    <h3>已完成</h3><span id="donecount"></span>
                </section>
                <ul id="donelist">
        
                </ul>
            </section>
    </section>
    

    <script>
        $(function(){
            // 每次刷新页面,都要直接显示原有的本地数据,即一刷新就将本地存储中已有的数据渲染到页面
            load();

            // input框获得焦点时,清空placeholder
            $('.todoinput').focus(function() {
                    $(this).prop("placeholder","");
                    // $(this).attr("style",'background:rgba(224,150,150,0.3);');//设置获得光标时输入框的背景颜色
            });
            // input框失去焦点时,设置placeholder
            $('.todoinput').blur(function() {
                    $(this).prop("placeholder",'添加todo');
                    // $(this).attr("style",'background:;');
            });

            // 读取本地存储的数据,更新本地存储数据,保存本地存储数据,将本地存储数据渲染到页面
            $('.todoinput').on('keydown',function(e) {
                // 回车事件
                if(e.keyCode===13) {
                    if($(this).val()=="") {
                        alert("输入内容不能为空!");
                    }else {
                        // 先获取本地存储中的数据
                        var local = getData();
                        // 更新数据
                        local.push({title: $(this).val(),done:false});
                        // 更新后的数据保存到本地存储
                        saveData(local);
                        //渲染页面
                        load();
                        
                        $(this).val("");// 回车后要将input框的内容清空
                        $(this).prop("placeholder",'添加todo');//回车后回复placeholder
                        // $(this).attr("style",'background:;');//回车后回复输入框背景颜色
                        // 回车后如何失去光标????????????????
                    }  
                }
            });

             // 读取本地存储数据
             function getData() {
                var data = localStorage.getItem("list");//读取本地存储中的数据,注意本地存储的数据只能是字符串格式
                // -------------console.log(typeof(data));//string
                if(data !== null){//如果有数据,就将字符串数据转json对象并返回数据
                    return JSON.parse(data);//JSON.parse()里面必须是一个字符串  如果此处报错,可能是data为undefined,可能是本地存储中的数据格式错误,application清空数据即可
                }else{//如果没有数据就返回一个空数组
                    return [];
                }
            }

            // 保存本地存储数据    注意本地存储数据都是字符串类型
            function saveData(param) {
                localStorage.setItem("list",JSON.stringify(param));
            };

            // 加载本地存储数据渲染到页面中
            function load() {
                var hh = getData();//获取本地数据,得到的是字符串数组
                // 回车事件调用渲染方法时,每次都将本地存储的所有数据遍历一遍添加进列表,如果不先清除列表的话,再加载又会重新渲染一次之前的数据。所以:遍历本地存储之前,先将ul,ol的数据清空
                $('ul,ol').empty();
                // 计算正在进行的事件数量,已经完成的事件数量
                var todocount=0;
                var donecount=0;
                // 遍历数组
                $.each(hh,function(i,n) {
                    // 本地存储里的数据分两种,已经完成的和正在进行的
                    if(n.done==false){
                        // 如果遍历到的当前元素是正在进行的数据,放入对应的ol中
                        $('ol').prepend("<li><input type='checkbox' class='check'><span class='content'>"+n.title+"</span><a href='javascript:;' class='del' id="+i+"></a></li>");
                        todocount++;//每添加一个Li,count加1
                    }else if(n.done==true) {
                        $('ul').prepend("<li><input type='checkbox' class='check' checked='false'><span class='content'>"+n.title+"</span><a href='javascript:;' class='del' id="+i+"></a></li>");
                        donecount++;
                    }
                });
                // 将count值赋值给span  注意用val()无效  一刷新页面就有数据,回车就有数据,所以写在load()里面
                $('#todocount').text(todocount);
                $('#donecount').text(donecount);
            };

            // 点击复选框,ul,ol的数据相互切换   修改done属性,done为false就是正在进行,done为true就是已完成
            $('ul,ol').on('click','input',function() {
                //获取本地存储数据
                var data = getData();
                // 找到当前li所对应的本地存储中的数据,将该数据的done属性修改
                var index = $(this).siblings('a').attr('id');//获取自定义属性用attr()
                console.log($(this).prop('checked'));//被选中的复选框checked属性为true
                console.log($(this).parent().siblings('li').children('input').prop('checked'));//未被选中的复选框checked属性为false        
                //-----------------将复选框的checked属性值赋给done false or true
                // ?为什么点击正在进行的复选框不会勾选----------因为一点击,就重新渲染页面把该条数据给放到已完成列表了
                data[index].done = $(this).prop('checked');
                // 将具有新checked属性的数据保存在本地存储
                saveData(data);
                // 重新渲染页面
                load();
            });

            // 点击a标签删除当前li  !!!!!!!!!!!!注意:不是删除页面元素,而是从本地存储中删除数据
            $('ul,ol').on('click','a',function() {//注意!!!?????直接用类名表示两个列表中的a标签会出问题,为什么???????????????????
                var info = getData();
                // 获取到当前a的索引号,然后从本地存储中找到相对应索引号的数据,删除
                var index = $(this).attr("id");
                // 删除数组的某个元素用splice(数组下标,个数)
                info.splice(index,1);//从索引index处开始,删除一个元素
                saveData(info);
                load();
            });

        })
    
    </script>
</body>
</html>

 

上一篇:案例-todolist计划列表[基本代码]


下一篇:案例-todolist计划列表【添加计划】