zoukankan      html  css  js  c++  java
  • jQuery模仿ToDoList实现简单的待办事项列表

    功能:在文本框中输入待办事项按下回车后,事项会出现在未完成列表中;点击未完成事项前边的复选框后,该事项会出现在已完成列表中,反之亦然;点击删除按钮会删除该事项;双击事项可以修改事项的内容。待办事项的数据是保存到本地存储的(localStorage),就算关闭页面再打开,数据还是存在的(前提是要用相同浏览器)。

    ToDoList链接:ToDoList—最简单的待办事项列表

    先把css样式以及js文件引入进来,jQuery文件要写在你自己的js文件上边

    <link rel="stylesheet" href="css/index.css">
    <script src="js/jquery.min.js"></script>
    <script src="js/todolist.js"></script>

    HTML代码:

     1 <body>
     2     <header>
     3         <section>
     4             <label for="title">ToDoList</label>
     5             <input type="text" id="title" name="title" placeholder="添加ToDo" required="required" autocomplete="off" />
     6         </section>
     7     </header>
     8     <section>
     9         <h2>正在进行 <span id="todocount"></span></h2>
    10         <ol id="todolist" class="demo-box">
    11 
    12         </ol>
    13         <h2>已经完成 <span id="donecount"></span></h2>
    14         <ul id="donelist">
    15 
    16         </ul>
    17     </section>
    18     <footer>
    19         Copyright &copy; 2019 
    20     </footer>
    21 </body>
      1 body {
      2     margin: 0;
      3     padding: 0;
      4     font-size: 16px;
      5     background: #CDCDCD;
      6 }
      7 
      8 header {
      9     height: 50px;
     10     background: #333;
     11     background: rgba(47, 47, 47, 0.98);
     12 }
     13 
     14 section {
     15     margin: 0 auto;
     16 }
     17 
     18 label {
     19     float: left;
     20     width: 100px;
     21     line-height: 50px;
     22     color: #DDD;
     23     font-size: 24px;
     24     cursor: pointer;
     25     font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
     26 }
     27 
     28 header input {
     29     float: right;
     30     width: 60%;
     31     height: 24px;
     32     margin-top: 12px;
     33     text-indent: 10px;
     34     border-radius: 5px;
     35     box-shadow: 0 1px 0 rgba(255, 255, 255, 0.24), 0 1px 6px rgba(0, 0, 0, 0.45) inset;
     36     border: none
     37 }
     38 
     39 input:focus {
     40     outline-width: 0
     41 }
     42 
     43 h2 {
     44     position: relative;
     45 }
     46 
     47 span {
     48     position: absolute;
     49     top: 2px;
     50     right: 5px;
     51     display: inline-block;
     52     padding: 0 5px;
     53     height: 20px;
     54     border-radius: 20px;
     55     background: #E6E6FA;
     56     line-height: 22px;
     57     text-align: center;
     58     color: #666;
     59     font-size: 14px;
     60 }
     61 
     62 ol,
     63 ul {
     64     padding: 0;
     65     list-style: none;
     66 }
     67 
     68 li input {
     69     position: absolute;
     70     top: 2px;
     71     left: 10px;
     72     width: 22px;
     73     height: 22px;
     74     cursor: pointer;
     75 }
     76 
     77 p {
     78     margin: 0;
     79 }
     80 
     81 li p input {
     82     top: 3px;
     83     left: 40px;
     84     width: 70%;
     85     height: 20px;
     86     line-height: 14px;
     87     text-indent: 5px;
     88     font-size: 14px;
     89 }
     90 
     91 li {
     92     height: 32px;
     93     line-height: 32px;
     94     background: #fff;
     95     position: relative;
     96     margin-bottom: 10px;
     97     padding: 0 45px;
     98     border-radius: 3px;
     99     border-left: 5px solid #629A9C;
    100     box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07);
    101 }
    102 
    103 ol li {
    104     cursor: move;
    105 }
    106 
    107 ul li {
    108     border-left: 5px solid #999;
    109     opacity: 0.5;
    110 }
    111 
    112 li a {
    113     position: absolute;
    114     top: 2px;
    115     right: 5px;
    116     display: inline-block;
    117     width: 14px;
    118     height: 12px;
    119     border-radius: 14px;
    120     border: 6px double #FFF;
    121     background: #CCC;
    122     line-height: 14px;
    123     text-align: center;
    124     color: #FFF;
    125     font-weight: bold;
    126     font-size: 14px;
    127     cursor: pointer;
    128 }
    129 
    130 footer {
    131     color: #666;
    132     font-size: 14px;
    133     text-align: center;
    134 }
    135 
    136 footer a {
    137     color: #666;
    138     text-decoration: none;
    139     color: #999;
    140 }
    141 
    142 @media screen and (max-device- 620px) {
    143     section {
    144         width: 96%;
    145         padding: 0 2%;
    146     }
    147 }
    148 
    149 @media screen and (min- 620px) {
    150     section {
    151         width: 600px;
    152         padding: 0 10px;
    153     }
    154 }
    index.css

    接下来开始写我们自己的js代码

    将多次使用的代码封装成函数,方便使用

    ①获取本地存储的数据。如果本地有数据则直接获取过来,没有数据的话就返回一个空数组

    1 function getDate() {
    2     var data = localStorage.getItem("todolist");   // 将获取到的数据赋给data
    3     if(data !== null) {     // 如果本地有数据,则返回数据
    4         return JSON.parse(data);  // 本地存储只能存储字符串,所以要想获取里边的数据就必须将字符串转换为数组形式返回
    5     } else { 
    6         return [];   // 如果本地没有数据,则返回一个空数组
    7     }
    8 }

    ②保存本地存储数据

    1 function saveDate(data) {
    2     // 用JSON.stringify()将数组转化成字符串保存到本地存储
    3     localStorage.setItem("todolist", JSON.stringify(data));
    4 }

    ③渲染页面 加载数据

    先将本地存储数据获取过来;将他们遍历(遍历之前先将列表清空),看他们是否已经被完成(通过数组里我们自己添加的done的值为true还是false来判断),如果已经被完成则添加到ul列表,否则添加进ol列表里;同时声明两个变量来保存已完成和未完成事项的个数

     1 function load() {
     2     var data = getDate();    // 先获取本地存储数据
     3 
     4     // 遍历本地存储数据 将他们添加到列表中
     5     $("ol, ul").empty();   // 遍历之前先清空列表
     6     var doneCount = 0;  // 已经完成的个数
     7     var todoCount = 0;  // 正在进行的个数
     8     $.each(data, function(i, ele) {    // i为索引 ele为遍历对象
     9         // 如果复选框被选中(已完成done: true)添加到ul里,未被选中(未完成done: false)添加到ol里
    10         if(ele.done) {
    11             $("ul").prepend("<li><input type='checkbox' checked='checked' > <p>" + ele.title + "</p> <a href='javascript:;' index=" + i + "></a></li>");
    12             doneCount++;  // 每添加一个li,已完成数加一
    13         } else {
    14             $("ol").prepend("<li><input type='checkbox'> <p>" + ele.title + "</p> <a href='javascript:;' index=" + i + "></a></li>");
    15             todoCount++;
    16         }
    17     })
    18     $("#donecount").text(doneCount);
    19     $("#todocount").text(todoCount);
    20 }

    1. 用户输入待办事项按下回车,将事项添加进列表

    给文本框绑定键盘按下事件,通过ASCII值来判断用户是否按下了回车(回车的ASCII值为13);

    不能直接在本地存储里更改数据,所以要先获取数据(数组形式),把数组进行更新数据(把最新数据追加给数组),再保存到本地存储;

    然后对页面进行重新渲染 更新数据

     1 load();   // 第一步先渲染页面,不然一开始刷新页面时列表不显示
     2 $("#title").on("keydown", function(event) {
     3     if(event.keyCode === 13) {
     4         if($(this).val().trim() !== "") {  // trim()去除字符串两侧空格
     5             var data = getDate();       // 获取本地存储数据
     6             // 把数组进行更新数据,把最新数据追加给数组
     7             data.push({title: $(this).val(), done: false});
     8             saveDate(data);      // 保存到本地存储
     9             load();              // 渲染加载到页面
    10             $(this).val("");
    11         }
    12     }
    13 })

    2. 删除待办事项

    先获取本地存储数据;

    用attr获取自定义属性index(索引)得到用户点击的第几个事项,通过索引删除数组里对应的那组数据;

    将更新过的数组保存到本地存储 再渲染给页面

    1 $("ol, ul").on("click", "a", function() {
    2     var data = getDate();    // 获取本地数据(data是局部变量,不用担心冲突)
    3     var index = $(this).attr("index");   // 用attr获取自定义属性index,得到索引
    4     // splice(index, num)删除数组对象  index为开始删除的位置,num为删除几个
    5     data.splice(index, 1);
    6     saveDate(data);
    7     load();
    8 })

    3. 用户点击复选框来选择事项已完成或未完成

    获取本地存储数据;

    通过复选框的兄弟a的index属性来获取用户点击的事项的索引(index),将第index个数据的done属性值修改为复选框的值;

    将更新过的数组保存到本地存储 再渲染给页面

    1 $("ol, ul").on("click", "input", function() {
    2     var data = getDate();
    3     // 利用a获取用户点击的第几个复选框
    4     var index = $(this).siblings("a").attr("index");
    5     // 修改数据:data[索引].属性名  获取固有属性用prop
    6     data[index].done = $(this).prop("checked");
    7     saveDate(data);
    8     load();
    9 })

     4. 用户可以通过双击事项进行修改

    获取本地存储数据;通过a获取索引index;

    在p里创建一个文本框,把p原来的内容赋给文本框,并让其为选中状态;

    当文本框失去焦点或用户点击回车,将修改后的内容给当前数组对象的title属性;

    将更新过的数组保存到本地存储 再渲染给页面

     1 $("ol, ul").on("dblclick", "p", function() {
     2     var data = getDate();
     3     var index = $(this).siblings("a").attr("index");
     4     // 先将p原来的内容获取过来
     5     var str = $(this).text();
     6     // 创建一个文本框,直接添加到p里
     7     $(this).prepend('<input type="text" />');
     8     // 将原来内容给文本框,并让其为选中(select)状态
     9     var input = $(this).children();
    10     input.val(str);
    11     input.select();
    12     // 当文本框失去焦点,将修改过的文本框的内容给title
    13     $(input).on("blur", function() {
    14         data[index].title = input.val();
    15         saveDate(data);
    16         load();
    17     })
    18     // 按下回车时保存修改
    19     $(input).on("keyup", function(e) {
    20         if(e.keyCode === 13) {   // 回车ASCII值为13
    21             // 手动调用点击事件
    22             this.blur();
    23         }
    24     })
    25 })

    详细JS代码:

     1 $(function() {
     2     load();   // 第一步先渲染页面,不然一开始刷新页面时列表不显示
     3     // 1、给文本框绑定键盘按下事件
     4     $("#title").on("keydown", function(event) {
     5         if(event.keyCode === 13) {
     6             if($(this).val().trim() !== "") {  // trim()去除字符串两侧空格
     7                 var data = getDate();       // 获取本地存储数据
     8                 // 把数组进行更新数据,把最新数据追加给数组
     9                 data.push({title: $(this).val(), done: false});
    10                 saveDate(data);      // 保存到本地存储
    11                 load();              // 渲染加载到页面
    12                 $(this).val("");
    13             }
    14         }
    15     })
    16     //2、删除待办事项
    17     $("ol, ul").on("click", "a", function() {
    18         var data = getDate();    // 获取本地数据(data是局部变量,不用担心冲突)
    19         var index = $(this).attr("index");   // 用attr获取自定义属性index,得到索引
    20         // splice(index, num)删除数组对象  index为开始删除的位置,num为删除几个
    21         data.splice(index, 1);
    22         saveDate(data);
    23         load();
    24     })
    25     //3、正在进行和已完成
    26     $("ol, ul").on("click", "input", function() {
    27         var data = getDate();
    28         // 利用a获取用户点击的第几个复选框
    29         var index = $(this).siblings("a").attr("index");
    30         // 修改数据:data[索引].属性名  获取固有属性用prop
    31         data[index].done = $(this).prop("checked");
    32         saveDate(data);
    33         load();
    34     })
    35     // 4、修改事项
    36     $("ol, ul").on("dblclick", "p", function() {
    37         var data = getDate();
    38         var index = $(this).siblings("a").attr("index");
    39         // 先将p原来的内容获取过来
    40         var str = $(this).text();
    41         // 创建一个文本框,直接添加到p里
    42         $(this).prepend('<input type="text" />');
    43         // 将原来内容给文本框,并让其为选中(select)状态
    44         var input = $(this).children();
    45         input.val(str);
    46         input.select();
    47         // 当文本框失去焦点,将修改过的文本框的内容给title
    48         $(input).on("blur", function() {
    49             data[index].title = input.val();
    50             saveDate(data);
    51             load();
    52         })
    53         // 按下回车也可以保存修改
    54         $(input).on("keyup", function(e) {
    55             if(e.keyCode === 13) {   // 回车ASCII值为13
    56                 // 手动调用点击事件
    57                 this.blur();
    58             }
    59         })
    60     })
    61     // 获取本地存储数据
    62     function getDate() {
    63         var data = localStorage.getItem("todolist");   // 将获取到的数据赋给data
    64         if(data !== null) {     // 如果本地有数据,则返回数据
    65             return JSON.parse(data);  // 本地存储只能存储字符串,所以要获取里边的数据就必须将字符串转换为数组形式返回
    66         } else { 
    67             return [];   // 如果本地没有数据,则返回一个空数组
    68         }
    69     }
    70     // 保存本地存储数据
    71     function saveDate(data) {
    72         // 用JSON.stringify()将数组转化成字符串保存到本地存储
    73         localStorage.setItem("todolist", JSON.stringify(data));
    74     }
    75     // 渲染加载数据
    76     function load() {
    77         var data = getDate();    // 先获取本地存储数据
    78 
    79         // 遍历本地存储数据 将他们添加到列表中
    80         $("ol, ul").empty();   // 遍历之前先清空列表
    81         var doneCount = 0;  // 已经完成的个数
    82         var todoCount = 0;  // 正在进行的个数
    83         $.each(data, function(i, ele) {    // i为索引 ele为遍历对象
    84             // 如果复选框被选中(已完成done: true)添加到ul里,未被选中(未完成done: false)添加到ol里
    85             if(ele.done) {
    86                 $("ul").prepend("<li><input type='checkbox' checked='checked' > <p>" + ele.title + "</p> <a href='javascript:;' index=" + i + "></a></li>");
    87                 doneCount++;  // 每添加一个li,已完成数加一
    88             } else {
    89                 $("ol").prepend("<li><input type='checkbox'> <p>" + ele.title + "</p> <a href='javascript:;' index=" + i + "></a></li>");
    90                 todoCount++;
    91             }
    92         })
    93         $("#donecount").text(doneCount);
    94         $("#todocount").text(todoCount);
    95     }
    96 })
  • 相关阅读:
    Python之Pyautogui模块20180125《PYTHON快速上手让繁琐的工作自动化》18章
    〈Android 群英传-神兵利器〉第7章一个的寂寞与一群人的狂欢
    一,Android Studio笔记
    一、探索 Android Studio
    微服务之网关:Ocelot+Consul实现动态集群扩展
    MacOS任意降级
    微服务之注册服务与发现:Consul在Windows下安装使用
    .Net Core中使用 AutoMapper
    .Net Core中使用Swagger
    .NetCore中使用EF Core
  • 原文地址:https://www.cnblogs.com/sunyan-blog/p/11967041.html
Copyright © 2011-2022 走看看