[TOC]
# jquery 清单应用 3.0 需要实现的功能
1. 点击查看详情
2. 设置定时任务
3. 美化弹框
4. 美化 checkbox
5. 从垃圾筐物理删除
# 首先还是布局...
不过我实在不想布局了
css 让我`超受伤`...
骚年, 你还在重复造轮子吗?
什么是重复造轮子?
比如你要造一台汽车, 难道轮子也要自己造一个吗?
有专门的人来造轮子, 我们直接拿来用就好了, 如果自己造轮子, 浪费时间不说, 如果你造出来的轮子, 还不圆呢?
比如这样...


还好吧, 又不是不能跑... 
关键是, 既浪费时间, 效果又不好, 最重要的是, **程序员都比较懒**...
今天来给大家带来一个神奇 UI 框架 `layui`

首先我们先下载...
让后导入到项目
在`index.html`同级目录, 拷入`layui`文件夹

让后在`index.html` 中引入

注意顺序, `jquery.js`最先引入, 其次是`layui.js`, 因为 layui 是基于 jquery 开发的
我们自己写的 js 放在最后, 因为我们的代码既用到了`jquery`,又用到了`layui`
注意文档中对`layui.js`和`layui.all.js`的说明...
> 模块化, 需要哪个, 引入哪个, 非模块化, 全部引用, 需要直接用, 会比较占带宽资源
然后咱们在`index.js`写个弹框试试效果
一言不合就弹框... 

看看效果...

可以弹框, 但是没有字... hello world 不见了...
不是不见了, 是因为...

因为是白色, 所以看不见, 我们把它注释了...


可以看到字了, 但是标题好像变黑了, 其他还好, 那么我们单独为`h1`加一个字体颜色吧
```css
h1.myTitle {
text-align: center;
margin: 20px;
color: #fff;
}
```

这回就完美了...
接下来, 我们就可以直接写 js 了... 
# 书写 js
不过我们需要先把原来的代码, 加到`layui.use()`中

第一个需求是, 点击`task-item`, 展示详情
展示内容, 我们可以使用 layer 的`tips`....

不过首先有一个问题, 之前我们对于过长的内容, 都进行了的压缩...
所以, 关于内容, 我们其实需要两个属性, `content`,`fullContent`,
所以我们还需要增加一个`fullContent`来保存所有`内容`
先修改保存的对象(记得先把之前的 layer 的弹框测试给删掉...)


然后我们需要监听`task-item`的点击事件
先输出一下 index 属性值
> `return false;` 效果相当于打断点...


没有问题, 可以获取 index, 那么下一步, 我们获取`content`和`fullContent`...


也没有问题...
可以监听 onclick, 数据也有了, 接下来就可以愉快的展示了...

```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
}
);
});
```
看看效果...

多敲点字试试...

还行, 不过字有点小, 并且宽度有点窄

`area` 属性, 是个数字,设置宽高, 注意加`px`, `auto`表示高度自动, 我们再试试...

这就好很多, 除了字有点小...
而且 4s 的话, 字数少的时候, 嫌时间长, 字数多的时候, 嫌时间短, 最好能自己控制...
我们把事件调长一点, 然后用`开发者工具`(F12)试着调试一下

接下来, 我么你设置 css
```css
.layui-layer-tips .layui-layer-content {
line-height: 28px;
font-size: 18px;
}
```
看看效果...

还是没变... 
**_注意 css 的顺序问题..._**

我们调一下顺序, 再试一下...


夭寿啊~~~ 
什么情况? 说好的`就近原则`呢?
通过开发者工具, 发现我们的样式被覆盖了....

不是已经调整了优先级吗?
注意覆盖我们样式的 css 为`layer.css`

位置是在`layui\lay\modules\layer.js`
也就是说, css 是在 layui.js 文件里, 动态加载的, 因为我们的 css 在 js 之上, 所以根据就近原则, 瓦特了...
所以还得往下调...

这儿可以吗?

还是不行... 
因为你忘了 `document.ready`....
所以还要往下挪...
那我直接一撸到底吧....

我 TM 挪到这总行了吧...

还真行了...

实际上在这个位置...
当然这只是方案之一, 我们也可以祭出强大的`!important`
请看方案二...
```css
.layui-layer-tips .layui-layer-content {
line-height: 28px !important;
font-size: 18px !important;
}
```

依然完美...
但是, bug 不是这么轻易就甩得掉的...
`bug如风, 常伴吾身...`

是一个 div...

所以, 我们需要在 css 里, 改成 inline-block
```css
.layui-layer-tips .layui-layer-content {
line-height: 28px !important;
font-size: 18px !important;
display: inline-block;
}
```

没有问题, 但是还没完....

文字太长了...
我们需要加上折行...
```css
.layui-layer-tips .layui-layer-content {
line-height: 28px !important;
font-size: 18px !important;
display: inline-block;
word-break: break-all;
}
```

可以, 不过把 input 遮住了...
改成 3...


再加上圆角吧, 这样就不突兀了...
```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;
}
```

挺好, 样式调完了, 就这改功能吧...
# 新的需求...
我们之前的问题是这样的... 之前代码里写的是`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 生效了...
记得把折行测试注释掉...

现在我们尝试, 在其他位置点击, 使其关掉, 当然需要先设置一个很长的时间, 让 tips 不会自动消失...
其实设置 0, 为常亮

然后, 需要把 index 声明成全局变量, 并且监听 body 的点击事件...
```javascript
// layer的tips弹框索引值
var layerTipIndex = 0;
```

接下来, 监听 body...
```javascript
// 监听body的点击事件
$("body").on("click", function() {
if (layerTipIndex) {
layui.layer.close(layerTipIndex);
layerTipIndex = 0;
}
});
```
结果又是一闪而过...
可以代码我们已经注释了啊...

骚年, 还记得事件冒泡吗?
```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;
}
});
```
不过少年, 告诉你一个小秘密...
`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.... 
你们有没有发现, 按键无效了...
因为阻止了默认事件...
其实我只是想阻止空格的默认事件, 那么空格的默认事件是多少呢?
不猜了, 直接上代码...
```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