💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] # jquery 清单应用 3.0 需要实现的功能 1. 点击查看详情 2. 设置定时任务 3. 美化弹框 4. 美化 checkbox 5. 从垃圾筐物理删除 # 首先还是布局... 不过我实在不想布局了![img](https://box.kancloud.cn/b8ed88e5104f4dda78b644927c564dae_240x240.jpg) css 让我`超受伤`... 骚年, 你还在重复造轮子吗? 什么是重复造轮子? 比如你要造一台汽车, 难道轮子也要自己造一个吗? 有专门的人来造轮子, 我们直接拿来用就好了, 如果自己造轮子, 浪费时间不说, 如果你造出来的轮子, 还不圆呢? 比如这样... ![](https://box.kancloud.cn/b77b2192750d8dc5126529087e40da5e_426x240.gif) ![](https://box.kancloud.cn/ebbcae2c9081d1a06ccb75322217ed76_448x209.gif) 还好吧, 又不是不能跑... ![img](https://box.kancloud.cn/e825bd877798d3c632de751bc6421cd2_240x240.gif) 关键是, 既浪费时间, 效果又不好, 最重要的是, **程序员都比较懒**... 今天来给大家带来一个神奇 UI 框架 `layui` ![1545233055645](https://box.kancloud.cn/0f1bb2f36319c46f72831a822ae89894_1813x642.png) 首先我们先下载... 让后导入到项目 在`index.html`同级目录, 拷入`layui`文件夹 ![1545233207935](https://box.kancloud.cn/d3f759182c44ecc1ce585d1d34cfc3aa_301x464.png) 让后在`index.html` 中引入 ![1545233464849](https://box.kancloud.cn/bf929f9e6204afabacbd2439ce7ce541_1118x457.png) 注意顺序, `jquery.js`最先引入, 其次是`layui.js`, 因为 layui 是基于 jquery 开发的 我们自己写的 js 放在最后, 因为我们的代码既用到了`jquery`,又用到了`layui` 注意文档中对`layui.js`和`layui.all.js`的说明... > 模块化, 需要哪个, 引入哪个, 非模块化, 全部引用, 需要直接用, 会比较占带宽资源 然后咱们在`index.js`写个弹框试试效果 一言不合就弹框... ![img](https://box.kancloud.cn/476a8ff29996d16dff45c4a3a19b38fa_240x240.jpg) ![1545233780513](https://box.kancloud.cn/ca7a66d26a915803e2c3d8bf96102a56_1108x409.png) 看看效果... ![1545225786120](https://box.kancloud.cn/15d21800497e20f9407ac3cca830252e_1920x938.png) 可以弹框, 但是没有字... hello world 不见了... 不是不见了, 是因为... ![1545225824838](https://box.kancloud.cn/cf1ba82b179ecbd1faec458809d3e908_432x153.png) 因为是白色, 所以看不见, 我们把它注释了... ![1545225848082](https://box.kancloud.cn/57d76a65a46a751c440391d1fd954343_373x153.png) ![1545225868939](https://box.kancloud.cn/1a593229313c7eeee857b5cde00d89cb_1920x938.png) 可以看到字了, 但是标题好像变黑了, 其他还好, 那么我们单独为`h1`加一个字体颜色吧 ```css h1.myTitle { text-align: center; margin: 20px; color: #fff; } ``` ![1545225932241](https://box.kancloud.cn/7560f058d9548496bae73319ef81e6e9_1920x938.png) 这回就完美了...![img](https://box.kancloud.cn/f0887c4e4865d57fa43f04553066682c_255x255.gif) 接下来, 我们就可以直接写 js 了... ![img](https://box.kancloud.cn/c2f8e54aabaa5ca0585320fcc7dcc8f4_240x240.jpg) # 书写 js 不过我们需要先把原来的代码, 加到`layui.use()`中 ![1545233915165](https://box.kancloud.cn/2bd822cb5cc538dd941a5ad440a65dfc_1266x664.png) 第一个需求是, 点击`task-item`, 展示详情 展示内容, 我们可以使用 layer 的`tips`.... ![1545229762101](https://box.kancloud.cn/038af59c2c29f5d271f068912f7b1b16_1090x161.png) 不过首先有一个问题, 之前我们对于过长的内容, 都进行了的压缩... 所以, 关于内容, 我们其实需要两个属性, `content`,`fullContent`, 所以我们还需要增加一个`fullContent`来保存所有`内容` 先修改保存的对象(记得先把之前的 layer 的弹框测试给删掉...) ![1545226503306](https://box.kancloud.cn/80b62c58a5f0cb1e2964ecf7f8156868_1198x469.png) ![1545226539357](https://box.kancloud.cn/c437aac6936bbee85e36a004c5bf50be_1468x381.png) 然后我们需要监听`task-item`的点击事件 先输出一下 index 属性值 > `return false;` 效果相当于打断点... ![1545226822397](https://box.kancloud.cn/6b71bb8b14bc417504b73d9233f3f6e1_727x366.png) ![1545227055763](https://box.kancloud.cn/c13ed5859410325c458e0d80ec654892_1920x774.png) 没有问题, 可以获取 index, 那么下一步, 我们获取`content`和`fullContent`... ![1545227145867](https://box.kancloud.cn/6c1b1f73506d9c67d195213d548663d9_843x373.png) ![1545227205140](https://box.kancloud.cn/c469e9664e3e6616efd7520da5222e19_1920x938.png) 也没有问题... 可以监听 onclick, 数据也有了, 接下来就可以愉快的展示了... ![1545229787940](https://box.kancloud.cn/038af59c2c29f5d271f068912f7b1b16_1090x161.png) ```javascript //小tips layer.tips( "我是另外一个tips,只不过我长得跟之前那位稍有些不一样。", "吸附元素选择器", { tips: [1, "#3595CC"], // 位置和背景颜色 time: 4000 // 4s自动消失 } ); ``` 我们的代码是这样的... ```javascript // 监听task-item的点击事件 $(".task-item").on("click", function() { layui.layer.tips( aTaskList[$(this).attr("index")]["fullContent"], ".task-item[index=" + $(this).attr("index") + "]", { tips: [1, "#3595CC"], time: 4000 } ); }); ``` 看看效果... ![1545234123554](https://box.kancloud.cn/869a866df105e0af910c0ad333317e81_836x375.png) 多敲点字试试... ![1545234230672](https://box.kancloud.cn/5640e90571d592233bfb4e213165e062_822x671.png) 还行, 不过字有点小, 并且宽度有点窄 ![1545234267958](https://box.kancloud.cn/c94f01f68d1e04bc0e9c5809afdd6cee_875x324.png) `area` 属性, 是个数字,设置宽高, 注意加`px`, `auto`表示高度自动, 我们再试试... ![1545234332084](https://box.kancloud.cn/da74610c1d7a3973b7556a3295283454_982x440.png) 这就好很多, 除了字有点小... 而且 4s 的话, 字数少的时候, 嫌时间长, 字数多的时候, 嫌时间短, 最好能自己控制... 我们把事件调长一点, 然后用`开发者工具`(F12)试着调试一下 ![1545234545561](https://box.kancloud.cn/d214730843be1bf2cdd938a1690577a8_1373x884.png) 接下来, 我么你设置 css ```css .layui-layer-tips .layui-layer-content { line-height: 28px; font-size: 18px; } ``` 看看效果... ![1545234613539](https://box.kancloud.cn/dfe9e23ba760e43620ac021946f715e4_925x437.png) 还是没变... ![img](https://box.kancloud.cn/d69a5c621901499a1129de2a0dd0690f_200x200.jpg) **_注意 css 的顺序问题..._** ![1545234681889](https://box.kancloud.cn/caac1ccb180c9043d4e04ec0af63e20c_957x435.png) 我们调一下顺序, 再试一下... ![1545234710284](https://box.kancloud.cn/796614932a4f46ad464a9e3f1d2f18db_1064x398.png) ![1545236384655](https://box.kancloud.cn/de5f99bd520ffbe59bdfc6d3719c5253_881x625.png) 夭寿啊~~~ ![img](https://box.kancloud.cn/b49fb98124be36eae336d2b8746f2a61_400x400.png) 什么情况? 说好的`就近原则`呢? 通过开发者工具, 发现我们的样式被覆盖了.... ![1545236504249](https://box.kancloud.cn/87285932e24aad710a1f9a8a24b85ca3_1920x938.png) 不是已经调整了优先级吗? 注意覆盖我们样式的 css 为`layer.css` ![1545236585673](https://box.kancloud.cn/e6cd193dce1c69925c81e51a4d6997a8_1402x857.png) 位置是在`layui\lay\modules\layer.js` 也就是说, css 是在 layui.js 文件里, 动态加载的, 因为我们的 css 在 js 之上, 所以根据就近原则, 瓦特了... 所以还得往下调... ![1545236725276](https://box.kancloud.cn/e39ec31c88dfdb9ecd17c305487b2143_820x231.png) 这儿可以吗? ![1545236766118](https://box.kancloud.cn/08d6a34afd2a3f076988027b2c9c81a0_1920x927.png) 还是不行... ![img](https://box.kancloud.cn/a3c90b4a4140055c28a45accb532eccc_100x145.gif) 因为你忘了 `document.ready`.... 所以还要往下挪... 那我直接一撸到底吧.... ![1545236935152](https://box.kancloud.cn/44f4eb58bb4724e0ea2bb1af6cdf8b9c_838x251.png) 我 TM 挪到这总行了吧... ![1545236975857](https://box.kancloud.cn/1efc7a193184b42295e52a91686b0bfb_909x750.png) 还真行了... ![1545237009956](https://box.kancloud.cn/6975d2a46c468977338d0ce6a33a658c_606x173.png) 实际上在这个位置... 当然这只是方案之一, 我们也可以祭出强大的`!important` 请看方案二... ```css .layui-layer-tips .layui-layer-content { line-height: 28px !important; font-size: 18px !important; } ``` ![1545237099191](https://box.kancloud.cn/dce7fc3aa1ac5420ce38bce35e5aaf82_981x635.png) 依然完美...![img](https://box.kancloud.cn/b70e9d915ba7a515df5267061335da54_157x161.gif) 但是, bug 不是这么轻易就甩得掉的... `bug如风, 常伴吾身...` ![1545237266892](https://box.kancloud.cn/7850a71434c37f86e2a51e6186fbbb2d_789x183.png) 是一个 div... ![1545239075017](https://box.kancloud.cn/576d5f77d2a0d2c025fa63d2ee88659b_936x758.png) 所以, 我们需要在 css 里, 改成 inline-block ```css .layui-layer-tips .layui-layer-content { line-height: 28px !important; font-size: 18px !important; display: inline-block; } ``` ![1545239136087](https://box.kancloud.cn/78d73b0773195000040773ea81bd3401_766x266.png) 没有问题, 但是还没完.... ![1545239199318](https://box.kancloud.cn/bcdac33a66c84563af3a386301ff558b_1331x218.png) 文字太长了... 我们需要加上折行... ```css .layui-layer-tips .layui-layer-content { line-height: 28px !important; font-size: 18px !important; display: inline-block; word-break: break-all; } ``` ![1545239297542](https://box.kancloud.cn/dfc747a93543dfa90416b587635f112b_795x200.png) 可以, 不过把 input 遮住了... 改成 3... ![1545239347987](https://box.kancloud.cn/9a724c8b71766f2d07c7093ae83ac07d_774x350.png) ![1545239332272](https://box.kancloud.cn/9b6164cbd4d802dfda7252d3c920ae10_817x302.png) 再加上圆角吧, 这样就不突兀了... ```css .layui-layer-tips .layui-layer-content { line-height: 28px !important; font-size: 18px !important; word-break: break-all; display: inline-block; border-radius: 10px !important; } ``` ![1545239436794](https://box.kancloud.cn/796fb8ede29e035d75379f205b7a9322_729x307.png) 挺好, 样式调完了, 就这改功能吧... # 新的需求... 我们之前的问题是这样的... 之前代码里写的是`4000` > 4s 的话, 字数少的时候, 嫌时间长, 字数多的时候, 嫌时间短, 最好能自己控制... 如何自己控制呢? 我们尝试在蓝色 tips 外点击的话, 让它关掉... 需要`layer.close()` ```javascript $(".task-item").on("click", function() { var index = layui.layer.tips( aTaskList[$(this).attr("index")]["fullContent"], ".task-item[index=" + $(this).attr("index") + "]", { tips: [3, "#3595CC"], time: 4000, area: ["500px", "auto"] } ); layui.layer.close(index); }); ``` 理论上会一闪而过, 而他真的一闪而过了... 说明 close 生效了... 记得把折行测试注释掉... ![1545240076349](https://box.kancloud.cn/07e1dbda079163796184b53d4417c6a1_506x164.png) 现在我们尝试, 在其他位置点击, 使其关掉, 当然需要先设置一个很长的时间, 让 tips 不会自动消失... 其实设置 0, 为常亮 ![1545239882717](https://box.kancloud.cn/d74215b71db22bb0508e37b9a3711486_589x236.png) 然后, 需要把 index 声明成全局变量, 并且监听 body 的点击事件... ```javascript // layer的tips弹框索引值 var layerTipIndex = 0; ``` ![1545240008715](https://box.kancloud.cn/25079e4fba3a50237b09bbb9a940c3a7_755x314.png) 接下来, 监听 body... ```javascript // 监听body的点击事件 $("body").on("click", function() { if (layerTipIndex) { layui.layer.close(layerTipIndex); layerTipIndex = 0; } }); ``` 结果又是一闪而过... 可以代码我们已经注释了啊... ![1545240076349](https://box.kancloud.cn/07e1dbda079163796184b53d4417c6a1_506x164.png) 骚年, 还记得事件冒泡吗? ```javascript $(".task-item").on("click", function(ev) { layerTipIndex = layui.layer.tips( aTaskList[$(this).attr("index")]["fullContent"], ".task-item[index=" + $(this).attr("index") + "]", { tips: [3, "#3595CC"], time: 0, area: ["500px", "auto"] } ); ev.stopPropagation(); // 阻止事件冒泡 }); ``` 接下来, 我想按下任意其他按键, 也能关闭弹框... 一切都很完美, 除了空格... 因为空格有默认动作, 我们需要清除它... ```javascript $("body").on("keypress", function(ev) { ev.preventDefault(); // 清除按键的默认事件 if (layerTipIndex && ev.keyCode) { layui.layer.close(layerTipIndex); layerTipIndex = 0; } }); ``` 不过少年, 告诉你一个小秘密...![img](https://box.kancloud.cn/f89c4b343ccef1adc6aec5909b4d1144_270x270.png) `return false` == `ev.stopPropagation()`+`ev.preventDefault()` ```javascript $("body").on("keypress", function(ev) { if (layerTipIndex && ev.keyCode) { layui.layer.close(layerTipIndex); layerTipIndex = 0; } return false; // 效果一样 }); ``` ```javascript $(".task-item").on("click", function(ev) { layerTipIndex = layui.layer.tips( aTaskList[$(this).attr("index")]["fullContent"], ".task-item[index=" + $(this).attr("index") + "]", { tips: [3, "#3595CC"], time: 0, area: ["500px", "auto"] } ); return false; }); ``` 好, 再讲最后一个 bug.... ![img](https://box.kancloud.cn/b7e1b95b4a0f0791c44c032ead1b327e_280x200.jpg) 你们有没有发现, 按键无效了... 因为阻止了默认事件... 其实我只是想阻止空格的默认事件, 那么空格的默认事件是多少呢? 不猜了, 直接上代码... ```javascript $("body").on("keypress", function(ev) { console.log(ev.keyCode); if (layerTipIndex && ev.keyCode) { layui.layer.close(layerTipIndex); layerTipIndex = 0; if (ev.keyCode === 32) { return false; } } }); ``` 这次真的圆满了... 老规矩, 附上所有代码... ```javascript layui.use(["layer", "form"], function() { // 变量初始化, 判断, 如果缓存里有数据, 取出到aTaskList, 注意缓存需要解析, 否则直接取是一个字符串 // 不管有没有数据, aTaskList都是数组, 我们下面操作的就是数组 if (localStorage.getItem("task-list")) { // 解析用的是JSON.parse var aTaskList = JSON.parse(localStorage.getItem("task-list")); } else { // 如果缓存中没有数据, 则直接空数组 var aTaskList = []; } var layerTipIndex = 0; // 监听layer的tip的开启 // 展示html代码包裹以后的数据, 刷新内容区 // 进入页面的时候会调一次, 更新数组和缓存后, 也会调用 showTask(); $("body").on("click", function() { // 监听, 如果有值, 关掉tip if (layerTipIndex) { layui.layer.close(layerTipIndex); layerTipIndex = 0; } }); // $("body").on("keypress", function(ev) { // // 监听空格, 关掉tip // if (ev.keyCode === 32 && layerTipIndex) { // layui.layer.close(layerTipIndex); // layerTipIndex = 0; // } // }); // 任意键都可关闭tip $("body").on("keypress", function(ev) { // 监听所有按键, 关掉tip if (ev.keyCode && layerTipIndex) { if (ev.keyCode === 32) { ev.preventDefault(); } layui.layer.close(layerTipIndex); layerTipIndex = 0; } }); // 监听输入框的回车事件, 获取输入框的内容, 更新数组, 更新缓存, 刷新内容区 $(".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函数, 压缩内容, 超过长度加··· fullContent: $(this).val(), // 存储原始值(全文) 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函数, 压缩内容, 超过长度加··· fullContent: $(".add-task input[name=content]").val(), // 存储原始值(全文) 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 class="task-content hidden">' + value.fullContent + "</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(); }); // 监听task-item的点击事件, 监听div $(".task-item").on("click", function(ev) { //小tips // 获取内容第一种方式, 直接取对象属性 // layui.layer.tips(aTaskList[$(this).attr('index')]['fullContent'], ".task-item[index="+$(this).attr('index')+"]", { // tips: [2, "#3595CC"], // time: 4000 // }); // 第二种: 先存到span里, 然后隐藏, 但是内容在需要的时候, 可以取出来 layerTipIndex = layui.layer.tips( $( ".task-item[index=" + $(this).attr("index") + "] .hidden" ).html(), ".task-item[index=" + $(this).attr("index") + "]", { tips: [3, "#3595CC"], time: 0, area: ["500px", "auto"] } ); // ev.stopPropagation(); }); // 监听移出事件 $(".task-item").on("mouseleave", function() { layui.layer.close(layerTipIndex); }); } // 内容压缩, 如果超过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"); // } // }); } }); ``` ```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; } h1.myTitle { text-align: center; margin: 20px; color: #fff; } .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); } .hidden { display: none; } .layui-layer-tips .layui-layer-content { font-size: 18px !important; display: inline-block; word-break: break-all; line-height: 26px !important; border-radius: 10px !important; } ``` ```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" type="text/css" href="css/iconfont.css" /> <link rel="stylesheet" type="text/css" href="css/iconfont_2.css" /> <link rel="stylesheet" href="layui/css/layui.css" /> <link rel="stylesheet" href="css/style.css" /> <script src="js/jquery.js"></script> <script src="layui/layui.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> ```