jQuery模仿ToDoList實現簡單的待辦事項列表

来源:https://www.cnblogs.com/sunyan-blog/archive/2019/12/02/11967041.html

功能:在文本框中輸入待辦事項按下回車後,事項會出現在未完成列表中;點擊未完成事項前邊的覆選框後,該事項會出現在已完成列表中,反之亦然;點擊刪除按鈕會刪除該事項。待辦事項的數據是保存到本地存儲的(localStorage),就算關閉頁面再打開,數據還是存在的(前提是要用相同瀏覽器)。 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-width: 620px) {
143     section {
144         width: 96%;
145         padding: 0 2%;
146     }
147 }
148 
149 @media screen and (min-width: 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 })

 


您的分享是我們最大的動力!

更多相關文章
  • 構建表格 表格的基本元素包括:table、tr和td。table表示HTML文檔中的表格,支持border屬性,用於定義表格邊框的寬度;tr表示表格中的行;td表示表格中的單元格,包括如下屬性:1)colspan:規定單元格可橫跨的列數;2)rowspan:規定單元格可橫跨的行數; <table> ...
  • 原始數據類型: number, string, boolean, undefined, null, object 基本類型(簡單類型), 即值類型: number, string, boolean 複雜類型(引用類型): object 空類型:undefined, null 存儲空間 值類型的值在哪 ...
  • 1. 對象: 有屬性和方法,特指的某個事物 對象: 一組無序屬性的集合的鍵值對,屬性的值可以是任意的類型 2.JSON格式的數據:一般都是成對的,是鍵值對, json也是一個對象, 數據都是成對的, 一般json格式的數據無論是鍵還是值都是用雙引號括起來的 var json = { "name": ...
  • 在使用jquery-validate.js插件時可以做一些初始化配置在初始化jquery-validate.js對象的時候,將外部的一些配置和該插件內部的一些預設配置合併在一起,如果有相同的配置,前者覆蓋後者(預設)的配置 // Constructor for validator $.validat ...
  • JS是一門什麼樣的語言? 是一門解釋性的語言 是一門腳本語言 是一門弱類型語言,聲明變數都用var 是一門基於對象的語言 是一門動態類型的語言: 1. 代碼(變數)只有執行到這個位置的時候,才知道這個變數中到底存儲的是什麼,如果是對象,就有對象的屬性和方法,如果是變數就是變數的作用 2. 對象沒有什 ...
  • 1. 簡書類 實現效果 html代碼 <div class="container"> <form action="" class="parent"> <input type="text" class="search" placeholder="搜索"> <input type="button" na ...
  • javascript 報錯 string.split is not a function ...
  • 自定義html元素滑鼠右鍵菜單 實現思路 在觸發contextmenu事件時,取消預設行為(也就是阻止瀏覽器顯示自帶的菜單),獲取右鍵事件對象,來確定滑鼠的點擊位置,作為顯示菜單的left和top值 編碼實現 <!DOCTYPE html> <html> <head> <meta charset=" ...
一周排行
x