<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] # 前情回顧 上一節課, 我們做了 jquery 備忘清單(1.0) 1. 輸入內容在 input 框中回車, 或者點擊藍色按鈕, 可以把內容插入備忘內容區 需要確定回車的 keyCode(13) 1. 最后插入的排在最上面 數組 unshift 1. 如果文字內容過長, 展示時要有省略號 字符串 slice 1. 頁面刷新或者重啟瀏覽器, 內容不丟失 localStorage ## 昨天 html, css, js 的完整代碼 ```html <!DOCTYPE html> <html lang="zh"> <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" /> <link rel="stylesheet" href="css/style.css" /> <link rel="stylesheet" type="text/css" href="css/iconfont.css" /> <script src="js/jquery.js"></script> <script src="js/index.js"></script> <title>備忘清單</title> </head> <body> <!-- 總容器開始 --> <div class="container"> <h1 class="myTitle">我的備忘清單</h1> <!-- 輸入框和按鈕開始 --> <div class="add-task"> <input type="text" placeholder="寫下你的備忘吧..." name="content" /> <button>添加備忘</button> </div> <!-- 輸入框和按鈕結束 --> <!-- 清單列表開始 --> <div class="task-list"> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> </div> <!-- 清單列表結束 --> </div> <!-- 總容器結束 --> </body> </html> ``` ```css * { margin: 0; padding: 0; outline: none; -webkit-transition: background 200ms; -moz-transition: background 200ms; -ms-transition: background 200ms; -o-transition: background 200ms; transition: background 200ms; } body { background: #00334b; color: #fff; } h1.myTitle { text-align: center; margin: 20px; } .container { margin: 0 auto; /* background: red; */ max-width: 600px; } .task-item { background: #fff; color: #333; margin-bottom: 3px; cursor: pointer; padding: 10px; border-radius: 3px; } .task-item:hover { background: #ddd; } .iconfont { float: right; margin-right: 10px; } input[type="text"] { background: #ddd; float: left; width: 84%; margin-right: 1%; padding: 10px; -moz-box-sizing: border-box; /*Firefox3.5+*/ -webkit-box-sizing: border-box; /*Safari3.2+*/ -o-box-sizing: border-box; /*Opera9.6*/ -ms-box-sizing: border-box; /*IE8*/ box-sizing: border-box; -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); } input[type="text"]:focus, input[type="text"]:hover { background: #eee; } .add-task button { width: 15%; background: rgb(3, 174, 255); } .add-task button:hover { background: rgb(77, 195, 251); } input[type="text"], .add-task button { border: 0; height: 100%; } .add-task { height: 37px; } .task-list { margin: 10px 0; } input, button { border-radius: 3px; } .task-content { margin-left: 5px; } .iconfont:hover { filter: drop-shadow(0 0 0 black); } ``` ```javascript $(function() { /* 聲明變量 */ if (localStorage.getItem("task_list")) { aTaskList = JSON.parse(localStorage.getItem("task_list")); } else { aTaskList = []; } showTask(); /* 聲明函數 */ function showTask() { var taskHTML = ""; for (var i = 0; i < aTaskList.length; i++) { taskHTML += '<div class="task-item">'; taskHTML += '<span><input type="checkbox"></span>' + "\n"; taskHTML += '<span class="task-content">' + aTaskList[i] + "</span>"; taskHTML += '<span><i class="iconfont icon-del"></i></span>'; taskHTML += '<span><i class="iconfont icon-edit"></i></span>'; taskHTML += "</div>"; } $(".task-list").html(taskHTML); } /* 邏輯代碼 */ $("[name=content]").on("keypress", function(ev) { if (ev.keyCode === 13 && compressContent($(this).val())) { aTaskList.unshift(compressContent($(this).val())); localStorage.setItem("task_list", JSON.stringify(aTaskList)); $(this).val(""); showTask(); } }); $(".add-task button").on("click", function() { if (compressContent($("[name=content]").val())) { aTaskList.unshift(compressContent($("[name=content]").val())); localStorage.setItem("task_list", JSON.stringify(aTaskList)); $("[name=content]").val(""); showTask(); } }); // 文字過多, 就顯示省略號 function compressContent(str) { if (str.length >= 30) { return str.slice(0, 30) + "···"; } else { return str; } } }); ``` # 備忘清單 2.0 1. 主要內容分三塊, 未完成, 已完成, 邏輯刪除(回收站) 1. 三者之間可以互相轉化 # 整理樣式 首先, 我們需要把 html 的內容區分成三塊, 每一塊給一個不同的 class ![1545050410028](https://box.kancloud.cn/4340f5e055a924a90671830cdb9fd746_688x334.png) 這是原來的, 現在我復制`class`為`task-list`的 html 代碼 ```html <div class="task-list"> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> </div> <div class="task-list"> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> </div> <div class="task-list"> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> </div> ``` 結果就變成了這樣... ![1545050507188](https://box.kancloud.cn/409d572eaa5bcb08bc52bf9711fd9845_678x710.png) 然后, 我們為每一塊分配一個`class`, 第一塊是`task-list` 這個就不用變了... 分別是`task-list`,`task-done`,`task-deleted` ```html <div class="task-list"><!-- 代碼省略 --></div> <div class="task-done"><!-- 代碼省略 --></div> <div class="task-deleted"><!-- 代碼省略 --></div> ``` 這個時候再刷新... ![1545050757786](https://box.kancloud.cn/1458501ab49067407440f59fb8a308fa_662x760.png) 樣式錯了... 再來調調樣式... ```css .task-list, .task-done, .task-deleted { margin: 10px 0; } ``` ![1545050869825](https://box.kancloud.cn/8ab94d620dd5dc3fa4c542fa0b1d1cd0_734x766.png) 現在就恢復正常了, 不過背景應該區分開... ```css .task-done .task-item { background: #ccc; } .task-deleted .task-item { background: #a0a0a0; } ``` ![1545051427438](https://box.kancloud.cn/96c77f9da74ebc31729ce45ba7c944ef_666x782.png) 我們還需要給`已完成`加上刪除線 ```css .task-done .task-content { text-decoration: line-through; } ``` ![1545051938418](https://box.kancloud.cn/37665b7627193a59d4f5e3444dda96a7_641x229.png) `已完成` 不應該都是打鉤的嗎? ```html <span><input checked type="checkbox" /></span> ``` ![1545052079345](https://box.kancloud.cn/0960bbc376f83188dbcc7fa8ea11dcfc_631x233.png) `已完成`不應該有編輯按鈕吧, 點擊 checkbox, 返回`未完成`, 點擊垃圾桶, 扔到`回收站` ```html <div class="task-item"> <span><input checked type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> </div> ``` ![1545052204693](https://box.kancloud.cn/264498b3fd632516cf9e7430bc39e19c_622x228.png) 垃圾桶那一塊, `編輯`應該改成`還原`吧, 點擊`還原`, 哪來的回哪去, 點擊`刪除`,`徹底刪除` 看來我們需要新的圖標... ![1545053249266](https://box.kancloud.cn/273d9fda145c90d314d7b52c6a8ebafc_571x254.png) ```html <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-remove"></i></span> <span><i class="iconfont icon-undo"></i></span> </div> ``` ![1545053482379](https://box.kancloud.cn/f5b94fdd1f941336d828e0f87c92f7d2_615x237.png) 又要重新下載, 新增一個也需要全部再選擇一遍? 豈不是很麻煩? 是需要重新下載, 但是不麻煩, 因為阿里圖標支持新建項目, 來管理圖標 ![1545053418314](https://box.kancloud.cn/08d728debaea5bd1f8a09f2b9912f7be_789x306.png) 當然, 你也可以, 在原有`iconfont.css`的基礎上, 加上新的 css`iconfont.css` ![1545102393112](https://box.kancloud.cn/9f6f569f2af7b196680653ef36662e01_375x173.png) 前提是, 類名不要重復... ![1545102432104](https://box.kancloud.cn/a789502f5790244842eadfd3b041ee12_993x718.png) ![1545102447421](https://box.kancloud.cn/e14b5b6b777a3d76740e20e356cf5308_1338x726.png) 如果兩個圖標, 都叫`remove`, 但是內容不同怎么辦呢? 改 class 就好... ![1545102499762](https://box.kancloud.cn/086da09f75574f782d60f75c6cdda392_1326x693.png) 回收站不應該有`checkbox`吧... 那把他們干掉... ```html <div class="task-item"> <!-- <span><input type="checkbox" /></span> --> <span class="task-content">item content 1</span> <span><i class="iconfont icon-remove"></i></span> <span><i class="iconfont icon-undo"></i></span> </div> ``` ![1545053575793](https://box.kancloud.cn/a1b6fff43cfe487c29f7ed6bef243a55_633x468.png) 又對不齊了... ![img](https://box.kancloud.cn/277f0a542bd933a004a93cbc95162a2e_300x292.jpg) 試試 css 的`visibility: hidden;`? ```css .task-deleted input[type="checkbox"] { visibility: hidden; } ``` ![1545053869471](https://box.kancloud.cn/77c93696a41512a49421e976212fded2_627x463.png) 完美 ![img](https://box.kancloud.cn/49dfbb31317e2f224ff6316373e4f48d_440x440.jpg) 不過... 貌似`已完成`的 hover 背景, 不是很明顯... ![1545053962095](https://box.kancloud.cn/44b59d10bd391cf9972c9fabd8a86908_631x229.png) ```css .task-done .task-item:hover { background: #fffafa; } ``` ![1545054220097](https://box.kancloud.cn/4bf1a2426df7b5c5c4340bc3500daea3_628x230.png) 這回好多了... 到目前為止, 樣式就調理的差不多了, 不過眼尖的同學可能會發現, 文字和圖標, 好像不在一條直線上... ![1545055557111](https://box.kancloud.cn/f70fcb85449549cf51cfbb586603ef96_628x51.png) 因為文字和圖標的行高不一致... ![1545059123108](https://box.kancloud.cn/5c16b6a35f32f218b91c57dd93c0f706_273x76.png) ![1545059238916](https://box.kancloud.cn/7ad366432e13784b3d4712e4c9740eea_260x86.png) 設置一致的行高即可 ```css .iconfont { float: right; margin-right: 10px; line-height: 21px; } ``` ![1545058160555](https://box.kancloud.cn/a7ad19c1e84cb81bba7431ee809d3ef0_979x85.png) # 開始 js 搞定了樣式, 我們就可以寫 js 了. 首先, 我們要操作單個的`task-item`, 那我們就需要準確的定位... 所以我們需要一個索引`index` 同時, 我們還需要一些屬性, 標記他的狀態 `done`, `delete` 所以我們需要一個對象... 包含`index,done,delete.content` 同時我們之前又是遍歷的數組, 所以我們需要`數組裝對象` 首先, 我們需要`index`, 數組的`index`, 因為數組自帶索引, 我們就不用新建變量來保存索引了, 直接用就好 `index`的作用, 是告訴程序, 我們現在操作的是數組中的哪個元素 然后, 我們每次添加內容, 就不再是單純的保存內容了, 而是保存一個對象, 然后壓入數組... 所以, 我們需要修改新增`task-item`的兩個函數 ```javascript $("[name=content]").on("keypress", function(ev) { if (ev.keyCode === 13) { var oTaskItem = { content: $(this).val(), isDel: 0, isDone: 0 }; aTaskList.unshift(oTaskItem); localStorage.setItem("task_list", JSON.stringify(aTaskList)); $(this).val(""); showTask(); } }); $(".add-task button").on("click", function() { var oTaskItem = { content: compressContent($("[name=content]").val()), isDel: 0, isDone: 0 }; aTaskList.unshift(oTaskItem); localStorage.setItem("task_list", JSON.stringify(aTaskList)); $("[name=content]").val(""); showTask(); }); ``` 當然, 展示的相關函數, 也要變... ```javascript function showTask() { var taskHTML = ""; aTaskList.forEach(function(value, key) { taskHTML += '<div index="' + key + '" class="task-item">'; if (value.isDone) { taskHTML += '<span><input index="' + key + '" checked type="checkbox"></span>' + "\n"; } else { taskHTML += '<span><input index="' + key + '" type="checkbox"></span>' + "\n"; } taskHTML += '<span class="task-content">' + value.content + "</span>"; taskHTML += '<span><i index="' + key + '" class="iconfont icon-del"></i></span>'; taskHTML += '<span><i index="' + key + '" class="iconfont icon-edit"></i></span>'; taskHTML += "</div>"; }); $(".task-list").html(taskHTML); } ``` 如果屬性`isDone` 是 1(true)的話, 就讓`checkbox`選中... 同理, 當 checkbox 被選中時, 我們也需要讓對象的`isDone`變成 1, 所以我們需要監聽 checkbox 先寫一下監聽, 打印`index` ```javascript // 監聽checkbox $("input[type=checkbox]").click(function() { if (!$(this).attr("checked")) { console.log($(this).attr("index")); $(this).attr("checked", "checked"); } else { $(this).removeAttr("checked"); } }); ``` ![1545064018002](https://box.kancloud.cn/d614927ca5cd48883f95f28550bd1125_1920x811.png) 沒有問題... 然后我們開始改對象 先寫一個改對象的函數... ```javascript function changeObj(index, property, value) { var obj = aTaskList[index]; obj[property] = value; aTaskList[index] = obj; localStorage.setItem("task_list", aTaskList); } ``` 然后在 checkbox 改變時, 調用它 ```javascript $("input[type=checkbox]").on("click", function() { console.log("hello"); if (!$(this).attr("checked")) { changeObj($(this).attr("index"), "isDone", 1); $(this).attr("checked", "checked"); } else { changeObj($(this).attr("index"), "isDone", 0); $(this).removeAttr("checked"); } showTask(); }); ``` 然而, 發現, 只能點擊一次... 問題在于, 重新寫入 html 代碼后, 原來的代碼就沒有了. 所以需要把監聽, 寫在動態生成 html()代碼之后 ```javascript function showTask() { console.log(aTaskList); var taskHTML = ""; aTaskList.forEach(function(value, key) { taskHTML += '<div index="' + key + '" class="task-item">'; if (value.isDone) { taskHTML += '<span><input index="' + key + '" checked type="checkbox"></span>' + "\n"; } else { taskHTML += '<span><input index="' + key + '" type="checkbox"></span>' + "\n"; } taskHTML += '<span class="task-content">' + value.content + "</span>"; taskHTML += '<span><i index="' + key + '" class="iconfont icon-del"></i></span>'; taskHTML += '<span><i index="' + key + '" class="iconfont icon-edit"></i></span>'; taskHTML += "</div>"; }); $(".task-list").html(taskHTML); // 監聽checkbox $("input[type=checkbox]").on("click", function() { console.log("hello"); if (!$(this).attr("checked")) { changeObj($(this).attr("index"), "isDone", 1); $(this).attr("checked", "checked"); } else { changeObj($(this).attr("index"), "isDone", 0); $(this).removeAttr("checked"); } showTask(); }); } ``` checkbox 已經監聽, 對象已經改變, 剩下的就是把不同類型的 task, 分到不同組里... ```javascript function showTask() { console.log(aTaskList); $(".task-list").html(""); $(".task-done").html(""); aTaskList.forEach(function(value, key) { if (!value.isDone && !value.isDel) { var taskHTML = ""; taskHTML += '<div index="' + key + '" class="task-item">'; taskHTML += '<span><input index="' + key + '" type="checkbox" /></span>' + "\n"; taskHTML += '<span class="task-content">' + value.content + "</span>"; taskHTML += '<span><i index="' + key + '" class="iconfont icon-del"></i></span>'; taskHTML += '<span><i index="' + key + '" class="iconfont icon-edit"></i></span>'; taskHTML += "</div>"; $(".task-list").append(taskHTML); } if (value.isDone && !value.isDel) { var taskHTML = ""; taskHTML += '<div index="' + key + '" class="task-item">'; taskHTML += '<span><input index="' + key + '" checked type="checkbox" /></span>'; taskHTML += '<span class="task-content">' + value.content + "</span>"; taskHTML += '<span><i index="' + key + '" class="iconfont icon-del"></i></span>'; taskHTML += "</div>"; $(".task-done").append(taskHTML); } }); // 監聽checkbox $("input[type=checkbox]").on("click", function() { console.log("hello"); if (!$(this).attr("checked")) { changeObj($(this).attr("index"), "isDone", 1); $(this).attr("checked", "checked"); } else { changeObj($(this).attr("index"), "isDone", 0); $(this).removeAttr("checked"); } showTask(); }); } ``` ![1545066339514](https://box.kancloud.cn/1e3cd5033cc10ac1159fe47de41bb59b_704x742.png) 成功!!! 試了一下`取消完成`功能, 也是可以的 ![1545066480937](https://box.kancloud.cn/49a255cea7780acf1d67c2ef87f8b597_696x733.png) 現在`未完成`和`已完成`的互轉已經實現了!!! 接下來是未完成和`邏輯刪除`的互轉 在`showTask()`函數下 ```javascript // 監聽未完成的刪除按鈕 $(".task-item .icon-del").on("click", function() { changeObj($(this).attr("index"), "isDel", 1); showTask(); }); ``` 還要寫刪除的展示... ```javascript // 代碼省略... $(".task-deleted").html(""); aTaskList.forEach(function(value, key) { // 代碼省略... if (!value.isDone && value.isDel) { var taskHTML = ""; taskHTML += '<div index="' + key + '" class="task-item">'; taskHTML += '<span><input index="' + key + '" type="checkbox" /></span>'; taskHTML += '<span class="task-content">' + value.content + "</span>"; taskHTML += '<span><i index="' + key + '" class="iconfont icon-remove"></i></span>'; taskHTML += '<span><i index="' + key + '" class="iconfont icon-undo"></i></span>'; taskHTML += "</div>"; $(".task-deleted").append(taskHTML); } }); // 代碼省略... ``` 試一下效果 ![1545067207480](https://box.kancloud.cn/dfa5d98d818ebee886f402d9e0fcfbec_635x507.png) 沒有問題... 然后, 同理, 是被刪除 task 的還原 ```javascript // 監聽已刪除的還原按鈕 $(".task-deleted .icon-undo").on("click", function() { changeObj($(this).attr("index"), "isDel", 0); showTask(); }); ``` 其他代碼不用改, 試了一下, 也沒有問題... ![1545067429144](https://box.kancloud.cn/7b0212e2203e1028e185a729fda06855_668x506.png) 現在就剩下, 已完成和刪除的互轉了, 加油!!! 首先, 我們需要給`已完成`并且`已刪除`的 task 加上刪除線 先把 js 注釋掉, 免得影響我們的內容 ```html <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <link rel="stylesheet" href="css/style.css" /> <link rel="stylesheet" type="text/css" href="css/iconfont.css" /> <script src="js/jquery.js"></script> <!-- <script src="js/index.js"></script> --> <title>備忘清單</title> ``` 然后, 給元素增加一個 class`is-deleted`, 并且設置樣式 ```html <span><input type="checkbox" /></span> <span class="task-content is-deleted">item content 1</span> <span><i class="iconfont icon-remove"></i></span> <span><i class="iconfont icon-undo"></i></span> ``` ```css .task-done .task-content, .is-deleted { text-decoration: line-through; } ``` 我們看一下效果... ![1545067754678](https://box.kancloud.cn/292e365936b61f4d2e961ca6e7c3591a_728x822.png) 前三項是有刪除線的 那么我們現在可以寫 js 了... 先來`已完成`轉`已刪除` ```javascript // 監聽已完成的刪除按鈕 $(".task-done .icon-del").on("click", function() { changeObj($(this).attr("index"), "isDel", 1); showTask(); }); ``` ```javascript function showTask() { // 代碼省略... if (value.isDone && value.isDel) { var taskHTML = ""; taskHTML += '<div index="' + key + '" class="task-item">'; taskHTML += '<span><input index="' + key + '" type="checkbox" /></span>'; taskHTML += '<span class="task-content is-deleted">' + value.content + "</span>"; taskHTML += '<span><i index="' + key + '" class="iconfont icon-remove"></i></span>'; taskHTML += '<span><i index="' + key + '" class="iconfont icon-undo"></i></span>'; taskHTML += "</div>"; $(".task-deleted").append(taskHTML); } // 代碼省略... } ``` 我們把 js 的注釋去掉, 然后看一下效果... 沒有問題 ![1545068075421](https://box.kancloud.cn/3c41df409dcf4310fed26987cc619148_679x509.png) 試試還原? 也沒有問題! ![1545068165360](https://box.kancloud.cn/e9f845ee629c2728ca73ec267212e5c5_695x513.png) 最后, 請大家思考一個問題 如下圖 ![1545068218115](https://box.kancloud.cn/73c629817785639e18deeb6ca288d012_719x530.png) 能不能, 把刪除內容區域的`已完成`和`未完成`進行分組呢? 比如`已完成`在上, `未完成`在下? 機智如你, 一定會有答案的!!! ![img](https://box.kancloud.cn/c4a8975b9cf77e04bd9e518db0ee4aa8_240x240.jpg) 最后, 完整代碼 ```html <!DOCTYPE html> <html lang="zh"> <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" /> <link rel="stylesheet" href="css/style.css" /> <link rel="stylesheet" type="text/css" href="css/iconfont.css" /> <link rel="stylesheet" type="text/css" href="css/iconfont_2.css" /> <script src="js/jquery.js"></script> <script src="js/index.js"></script> <title>備忘清單</title> </head> <body> <!-- 總容器開始 --> <div class="container"> <h1 class="myTitle">我的備忘清單</h1> <!-- 輸入框和按鈕開始 --> <div class="add-task"> <input type="text" placeholder="寫下你的備忘吧..." name="content" /> <button>添加備忘</button> </div> <!-- 輸入框和按鈕結束 --> <!-- 清單列表開始 --> <div class="task-list"> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> <span><i class="iconfont icon-edit"></i></span> </div> </div> <div class="task-done"> <div class="task-item"> <span><input checked type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> </div> <div class="task-item"> <span><input checked type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> </div> <div class="task-item"> <span><input checked type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> </div> <div class="task-item"> <span><input checked type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> </div> <div class="task-item"> <span><input checked type="checkbox" /></span> <span class="task-content">item content 1</span> <span><i class="iconfont icon-del"></i></span> </div> </div> <div class="task-deleted"> <div class="task-item"> <span><input type="checkbox" /></span> <span class="is-deleted task-content">item content 1</span> <span><i class="iconfont icon-remove"></i></span> <span><i class="iconfont icon-undo"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="is-deleted task-content">item content 1</span> <span><i class="iconfont icon-remove"></i></span> <span><i class="iconfont icon-undo"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="is-deleted task-content">item content 1</span> <span><i class="iconfont icon-remove"></i></span> <span><i class="iconfont icon-undo"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="is-deleted task-content">item content 1</span> <span><i class="iconfont icon-remove"></i></span> <span><i class="iconfont icon-undo"></i></span> </div> <div class="task-item"> <span><input type="checkbox" /></span> <span class="is-deleted task-content">item content 1</span> <span><i class="iconfont icon-remove"></i></span> <span><i class="iconfont icon-undo"></i></span> </div> </div> <!-- 清單列表結束 --> </div> <!-- 總容器結束 --> </body> </html> ``` ```css * { margin: 0; padding: 0; outline: none; -webkit-transition: background 200ms; -moz-transition: background 200ms; -ms-transition: background 200ms; -o-transition: background 200ms; transition: background 200ms; } body { background: #00334b; color: #fff; } h1.myTitle { text-align: center; margin: 20px; } .container { margin: 0 auto; /* background: red; */ max-width: 600px; } .task-item { background: #fff; color: #333; margin-bottom: 3px; cursor: pointer; padding: 10px; border-radius: 3px; } .task-item:hover { background: #ddd; } .iconfont { float: right; margin-right: 10px; line-height: 21px; } input[type="text"] { background: #ddd; float: left; width: 84%; margin-right: 1%; padding: 10px; -moz-box-sizing: border-box; /*Firefox3.5+*/ -webkit-box-sizing: border-box; /*Safari3.2+*/ -o-box-sizing: border-box; /*Opera9.6*/ -ms-box-sizing: border-box; /*IE8*/ box-sizing: border-box; -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); } input[type="text"]:focus, input[type="text"]:hover { background: #eee; } .add-task button { width: 15%; background: rgb(3, 174, 255); } .add-task button:hover { background: rgb(77, 195, 251); } input[type="text"], .add-task button { border: 0; height: 100%; } .add-task { height: 37px; } .task-done .task-item { background: #ccc; } .task-deleted .task-item:hover { background: #ddd; } .task-done .task-item:hover { background: #fff; } .task-deleted .task-item { background: #a9a7a7; } .task-done, .task-deleted, .task-list { margin: 10px 0; } .task-done .task-content, .is-deleted { text-decoration: line-through; } .task-deleted input[type="checkbox"] { visibility: hidden; } input, button { border-radius: 3px; } .task-content { margin-left: 5px; } .iconfont:hover { filter: drop-shadow(0 0 0 black); } ``` ```javascript // 相當于$(document).ready(), html代碼, 加載完之后執行, 不會出現找不到對象的情況 $(function() { // 變量初始化, 判斷, 如果緩存里有數據, 取出到aTaskList, 注意緩存需要解析, 否則直接取是一個字符串 // 不管有沒有數據, aTaskList都是數組, 我們下面操作的就是數組 if (localStorage.getItem("task-list")) { // 解析用的是JSON.parse var aTaskList = JSON.parse(localStorage.getItem("task-list")); } else { // 如果緩存中沒有數據, 則直接空數組 var aTaskList = []; } // 展示html代碼包裹以后的數據, 刷新內容區 // 進入頁面的時候會調一次, 更新數組和緩存后, 也會調用 showTask(); // 監聽輸入框的回車事件, 獲取輸入框的內容, 更新數組, 更新緩存, 刷新內容區 $(".add-task input[name=content]").on("keypress", function(ev) { // 先判斷, 回車, 并且輸入框里有內容, 則進行邏輯操作(往下走) // 回車的keyCode的是13, 使用===來比較 if (ev.keyCode === 13 && $(this).val()) { // 聲明一個對象, 用來存儲輸入框里的內容(content) // 還有其他的屬性 // isDel, 用來標記是否邏輯刪除, 1 for yes, 0 for no // isDone, 用來標記是否已完成, 1 for yes, 0 for no var oTaskItem = { content: compressContent($(this).val()), // 存儲input框里的內容, compressContent函數, 壓縮內容, 超過長度加··· isDel: 0, // 標記已刪除 isDone: 0 // 標記已完成 }; updateData(oTaskItem); // 更新數組, 更新緩存, 刷新內容區 // 清空input輸入區的內容 $(this).val(""); } }); $(".add-task button").on("click", function() { if ($(".add-task input[name=content]").val()) { // 聲明一個對象, 用來存儲輸入框里的內容(content) // 還有其他的屬性 // isDel, 用來標記是否邏輯刪除, 1 for yes, 0 for no // isDone, 用來標記是否已完成, 1 for yes, 0 for no var oTaskItem = { content: compressContent( $(".add-task input[name=content]").val() ), // 存儲input框里的內容, compressContent函數, 壓縮內容, 超過長度加··· isDel: 0, // 標記已刪除 isDone: 0 // 標記已完成 }; updateData(oTaskItem); // 更新數組, 更新緩存, 刷新內容區 // 清空input輸入區的內容 $(".add-task input[name=content]").val(""); } }); // 更新內容區 // 數組和緩存變化后, 會調用, 刷新頁面也會調用 function showTask() { // 為什么置空(初始值為空字符串), 因為后面是追加, 所以追加之前, 內容最好為空, 其他特殊需求另說 // 保持數據類型一致, 是個好習慣, 通過給初始值, 來確定變量的數據類型 // 這里如果不給初始值, 會出現undefined字符串 var doneHTML = ""; // 已完成內容區的html代碼 var taskHTML = ""; // 未完成內容區的html代碼 var delHTML = ""; // 已刪除內容區的html代碼 console.log(aTaskList); // forEach遍歷數組, 參數是一個函數, 函數有兩個參數, 一個是value, 一個是key, 注意一下順序問題, value在前, key在后 aTaskList.forEach(function(value, key) { // 動態拼接html, 然后寫入 if (!value.isDone && !value.isDel) { // 未完成時, 進入 taskHTML += '<div index="' + key + '" class="task-item">'; taskHTML += '<span><input index="' + key + '" type="checkbox" /></span>' + "\n"; // 為什么有個\n, 為了保證和原來的html一致, 這個并不是必須的 taskHTML += '<span class="task-content">' + value.content + "</span>"; taskHTML += '<span><i index="' + key + '" class="iconfont icon-del"></i></span>'; taskHTML += '<span><i index="' + key + '" class="iconfont icon-edit"></i></span>'; taskHTML += "</div>"; } if (value.isDone && !value.isDel) { // 已完成, 進入 doneHTML += '<div index="' + key + '" class="task-item">'; // key的目的: key是對象在數組中的下標, 用來標記對象在數組中的位置 doneHTML += '<span><input checked index="' + key + '" type="checkbox" /></span>' + "\n"; doneHTML += '<span class="task-content">' + value.content + "</span>"; doneHTML += '<span><i index="' + key + '" class="iconfont icon-del"></i></span>'; doneHTML += '<span><i index="' + key + '" class="iconfont icon-edit"></i></span>'; doneHTML += "</div>"; } if (value.isDel) { // 已刪除, 進入 delHTML += '<div index="' + key + '" class="task-item">'; delHTML += '<span><input index="' + key + '" type="checkbox" /></span>'; // 加刪除線, 方式二, 直接判斷, 修改html if (value.isDone) { delHTML += '<span class="task-content is-deleted">' + value.content + "</span>"; } else { delHTML += '<span class="task-content">' + value.content + "</span>"; } delHTML += '<span><i index="' + key + '" class="iconfont icon-remove"></i></span>'; delHTML += '<span><i index="' + key + '" class="iconfont icon-undo"></i></span>'; delHTML += "</div>"; } }); $(".task-done").html(doneHTML); // 寫入"已完成區"的html代碼, 原來的都覆蓋了 $(".task-list").html(taskHTML); // 寫入"未完成區"的html代碼, 原來的都覆蓋了 $(".task-deleted").html(delHTML); // 寫入"已刪除區"的html代碼, 原來的都覆蓋了 // 監聽復選框 $("input[type=checkbox]").click(function() { if (!$(this).attr("checked")) { // 未選中狀態 ==> 已選中, 修改對象屬性, isDone ==> 1 aTaskList[$(this).attr("index")]["isDone"] = 1; // 實際上更新了的數組 } else { // 已選中狀態 ==> 未選中, 修改對象屬性, isDone ==> 0 aTaskList[$(this).attr("index")]["isDone"] = 0; // 實際上更新了的數組 } updateData(); // 牽涉到方法重載, 參數個數不同, 干不同的事 }); // 監聽未完成區的刪除按鈕(小垃圾桶) $(".task-item .icon-del").on("click", function() { // 修改當前對象的isDel屬性為1 aTaskList[$(this).attr("index")]["isDel"] = 1; // 改為1之后, html代碼也要相應的改變 updateData(); }); // 監聽已刪除區的還原按鈕 $(".task-deleted .icon-undo").on("click", function() { // 修改當前對象的isDel屬性為1 aTaskList[$(this).attr("index")]["isDel"] = 0; // 改為1之后, html代碼也要相應的改變 updateData(); }); // 監聽已完成區的刪除按鈕 $(".task-done .icon-del").on("click", function() { // 修改當前對象的isDel屬性為1 aTaskList[$(this).attr("index")]["isDel"] = 1; // 改為1之后, html代碼也要相應的改變 updateData(); }); } // 內容壓縮, 如果超過30個, 就截取30, 加上省略號, 如果不超過30, 原路返回 function compressContent(str) { if (str.length >= 30) { return str.slice(0, 30) + "···"; } else { return str; } } // 組合操作, 更新數組, 更新緩存, 更新html內容 function updateData(obj) { if (arguments.length) { // 把對象添加到數組, unshift, 保證最后添加的, 在第一個 aTaskList.unshift(obj); } // 更新完數組, 更新緩存, 保持數組中的數據和緩存中一致 localStorage.setItem("task-list", JSON.stringify(aTaskList)); // 刷新內容區 showTask(); // // 動態添加刪除線(方式一) // aTaskList.forEach(function(value, key) { // if (value.isDone) { // $(".task-item[index=" + key + "] .task-content").addClass("is-deleted"); // } // }); } }); ``` # 請問大家幾個問題 1. 中文和英文長度不一致, 怎么辦? 2. 壓縮后, 最后一個字符恰好是標點, 怎么辦? 3. 對象加入數組時, 如果用 push, 在展示時, 如何讓最后添加的對象, 第一個展示? 4. 能不能, 把刪除內容區域的已完成和未完成進行分組呢? 比如已完成在上, 未完成在下?
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看