[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>
```
- 每日单词
- JavaScript 入门
- JavaScript 基础
- JavaScript 基础回顾
- JavaScript 函数
- 匿名函数,多维数组,数据类型转换
- JavaScript 类型转换, 变量作用域
- js 运算符(一)
- js 运算符(二)
- js 流程控制语句
- JavaScript 扫盲日
- JavaScript 牛刀小试(一)
- JavaScript 牛刀小试(二)
- JavaScript 再谈函数
- JavaScript-BOM
- JavaScript-定时器(一)
- JavaScript-定时器(二)
- 番外-轮播图源码
- JavaScript 轮播图和 DOM 简介
- JavaScript-DOM 基础-NODE 接口-属性
- JavaScript-DOM 基础-NODE 接口-方法
- NodeList-接口-HTMLCollection-接口
- Document 节点
- CSS 复习与扩展(一)
- CSS 复习与扩展(二)
- 走进 jQuery 的世界
- 使用 jquery
- 使用 jquery-2
- jquery 中高级
- jquery 备忘清单-1
- jquery 备忘清单-2
- 聊聊 json
- jquery 备忘清单-3