功能:在文本框中輸入待辦事項按下回車後,事項會出現在未完成列表中;點擊未完成事項前邊的覆選框後,該事項會出現在已完成列表中,反之亦然;點擊刪除按鈕會刪除該事項。待辦事項的數據是保存到本地存儲的(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 © 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 })