通过前面的复习,这里做一个jQuery的练习,制作一个网页版的to do list
四个步骤逐步完成整个项目
第一步:完成基本的页面布局
大致是四个区域,分别是待处理、正在处理、已完成和最后的项目添加区域,为其简单的设定css和日期选择器
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>to do list program</title>
<link rel="stylesheet" href="jquery-ui.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="task-list" id="pending">
<h3>待处理</h3>
</div>
<div class="task-list" id="inprogress">
<h3>进行中</h3>
</div>
<div class="task-list" id="completed">
<h3>已完成</h3>
</div>
<div class="task-list">
<h3>添加项目</h3>
<form action="" method="post">
<input type="text" placeholder="标题" class="addtitle" />
<textarea placeholder="内容" class="adddescription"></textarea>
<input type="text" id="datepicker" class="addtime" placeholder="添加日期(月/年/日)" />
<input type="button" class="btn" value="添加项目" />
<input type="button" class="clear" value="清空所有项目" />
</form>
</div>
</body>
<script src="app.js"></script>
<script src="jquery-3.2.1.min.js"></script>
<script src="jquery-ui.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("#datepicker").datepicker();
});
</script>
</html>
随后我们再创建一个任务区域,由标题、时间以及内容组成,这个区域可以放在任意三个区域里,并且可以被删除
我们将要添加的区域加一些css,它是我们插入到待处理里的一个div
<div class="task-list" id="pending">
<h3>待处理</h3>
<div class="todo-task">
<div class="task-header">题目</div>
<div class="task-date">19/12/2018</div>
<div class="task-description">内容</div>
</div>
</div>
这个todo-task是个动态的,由区域四动态生成并且可以移动删除,这是初步的设定
第二步:实现后台代码的事件添加
通过js我们先实现后台添加一个事件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>to do list program</title>
<link rel="stylesheet" href="jquery-ui.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="task-list" id="pending">
<h3>待处理</h3>
<div class="todo-task" id="task-001">
<div class="task-header">题目</div>
<div class="task-date">19/12/2018</div>
<div class="task-description">内容</div>
</div>
</div>
<div class="task-list" id="inprogress">
<h3>进行中</h3>
</div>
<div class="task-list" id="completed">
<h3>已完成</h3>
</div>
<div class="task-list">
<h3>添加项目</h3>
<form id="todo-form">
<input type="text" placeholder="标题" class="addtitle" />
<textarea placeholder="内容" class="adddescription"></textarea>
<input type="text" id="datepicker" class="addtime" placeholder="添加日期(月/年/日)" />
<input type="button" class="btn" value="添加项目" />
<input type="button" class="clear" value="清空所有项目" />
</form>
<div id="delete-div" class="hidden">拖动到这里删除</div>
</div>
</body>
<script src="app.js"></script>
<script src="jquery-3.2.1.js"></script>
<script src="jquery-ui.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var myTodoList = new MyTodoList();
console.log("hello");
myTodoList.generateElement({
id:"123",
code:"2",
title:"console test",
date:"18/12/2018",
description:"this is a test"
})
});
</script>
</html>
var MyTodoList = (function(){
var defaults ={ //这里我们定义一些常量,用于在js里使用,它们分别是html中的类名以及id标识
todoTask:"todo-task",
taskHeader:"task-header",
taskDate:"task-date",
taskDescription:"task-description",
taskID:"task-",
formID:"todo-form",
deleteDiv:"delete-div"
},
codes = { //这里我们用三个数字分别代替三个区块,即让数字索引它们的id
"1":"#pending",
"2":"#inprogress",
"3":"#completed"
};
var MyTodoList =function(){
};
MyTodoList.prototype.generateElement = function(params){ //定义一个prototype function
var parent = $(codes[params.code]), //这里获取我们传入的参数让我们往哪个区块去添加,即找这个区域的父区域
wrapper;
if(!parent){
return;
}
wrapper = $('<div />',{ 定义这个区域
"class":defaults.todoTask,
"id":defaults.taskID+params.id,
"data":params.id
});
$('<div />',{ //定义它里面的标题小div
"class":defaults.taskHeader,
"text":params.title
}).appendTo(wrapper); //把他插入到wrapper里
$('<div />',{ //定义它里面的时间小div
"class":defaults.taskDate,
"text":params.date
}).appendTo(wrapper);
$('<div />',{ //定义它里面的内容小div
"class":defaults.taskDescription,
"text":params.description
}).appendTo(wrapper);
wrapper.appendTo(parent); //最后将创建好的整个div加到需要加的区域里
};
return MyTodoList;
})()
重点是app.js里的代码
第三步:实现添加删除以及按钮的绑定
我们此步完成在最右区域填写信息添加内容,并且可以用内容右上角的“X”删除相关内容
var MyTodoList = (function() {
var defaults = {
// CSS selectors and attributes that would be used by the JavaScript functions
todoTask: "todo-task",
todoHeader: "task-header",
todoDate: "task-date",
todoDescription: "task-description",
taskId: "task-",
formId: "todo-form",
dataAttribute: "data",
deleteDiv: "delete-div",
remove: "remove"
},
codes = { // For pending tasks
"1": "#pending",
"2": "#inProgress",
"3": "#completed"
},
data = {};
var MyTodoList = function() {
var _this = this;
$('#datepicker').datepicker(); //实现日期选择器
$('#addItem').click(function() { //添加项目内容绑定
var title = $(this).siblings('.addTitle').val(),
description = $(this).siblings('.addDescriptions').val(),
date = $(this).siblings('.addDate').val(),
//通过找到按钮的兄弟并且获得输入的内容
id = Date.now() + '';
_this.generateElement({ //调用构造内容的函数
id: id, //为了使id不重复 采用Date.now()获取唯一当前时间
code: "1",
title: title,
date: date,
description: description
});
$(this).siblings('.addTitle').val(''),
$(this).siblings('.addDescriptions').val(''),
$(this).siblings('.addDate').val('');
// 添加内容之后 清空输入框里的数据
$('body').on('click', '.todo-task .remove', function() {
var id = $(this).parent().attr('id').substring(defaults.taskId.length);
//为了调用删除函数 并且删除函数只需要一个id参数即可
_this.removeElement({
id: id
});
});
});
};
MyTodoList.prototype.generateElement = function(params) {
var parent = $(codes[params.code]),
wrapper;
if (!parent) {
return;
}
wrapper = $("<div />", {
"class": defaults.todoTask,
"id": defaults.taskId + params.id,
"data": params.id
});
$("<div />", { //加一个删除按钮
"class": defaults.remove,
"text": 'X'
}).appendTo(wrapper);
$("<div />", {
"class": defaults.todoHeader,
"text": params.title
}).appendTo(wrapper);
$("<div />", {
"class": defaults.todoDate,
"text": params.date
}).appendTo(wrapper);
$("<div />", {
"class": defaults.todoDescription,
"text": params.description
}).appendTo(wrapper);
wrapper.appendTo(parent);
};
MyTodoList.prototype.removeElement = function(params) {
$("#" + defaults.taskId + params.id).remove();
//通过id删除内容
};
return MyTodoList;
})()
第四步:实现LocalStorage 本地存储
实现本地存储的步骤是
- setItem
- getItem
- removeItem
分别绑定到添加项目和删除项目相应的handler中
MyTodoList.prototype.persistData = function() {
localStorage.setItem('Haris', JSON.stringify(this.data));
}
_this.data = JSON.parse(localStorage.getItem('Haris'))
for (var property in _this.data) {
if (_this.data.hasOwnProperty(property)) { //该对象是否有该方法
_this.generateElement({
id: property,
code: _this.data[property].code,
title: _this.data[property].title,
date: _this.data[property].date,
description: _this.data[property].description
});
}
_this.data[id] = {
code: "1",
title: title,
date: date,
description: description
};
_this.persistData();
removeItem绑定在“X”上
delete _this.data[id];
_this.persistData();
第五步:实现拖曳,将内容拖到任何区域,拖到删除区域进行删除
首先,我们将三个区域变成draggable 将四个区域(三个内容区域以及一个删除区域)删除区域我们让它只有拖拽时显示出来,不拖拽不显示
第一小步: 我们让每一个产生的内容区域都是可拖拽的,方法是在初始化时让其可拖拽
wrapper.draggable({
opacity: 0.5, //拖拽时 透明度减半
start: function() { //两个event start 和 stop 让删除区域显示和隐藏
$('#' + defaults.deleteDiv).show('fast');
},
stop: function() {
$('#' + defaults.deleteDiv).hide('fast');
}
});
第二小步: 为三个区域加上可拖拽属性
$.each(codes, function(index, value) { //用each遍历
$(value).droppable({ //给每个区域droppable添加drop以及回调函数
drop: function(event, ui) {
var element = ui.helper, //element是我们真在拖曳的内容
id = element.attr('id').substring(defaults.taskId.length), //获取id
item = _this.data[id];
item.code = index; //我们拖到哪个区域对应的code 就是each过程中的index
_this.removeElement({ //我们为了拖动时原来位置的内容就消失
id: id
});
_this.generateElement({ 在托动结束的地方生成该内容
id: id,
code: item.code,
title: item.title,
date: item.date,
description: item.description
});
_this.persistData();
}
});
});
第三小步: 设置删除区域
$('#' + defaults.deleteDiv).droppable({ //选择器选到该区域
drop: function(event, ui) { //添加drop
var element = ui.helper,
id = element.attr('id').substring(defaults.taskId.length);
_this.removeElement({ //同样传入id即可删除
id: id
});
delete _this.data[id]; //删掉这个内容
_this.persistData(); //更新数据库
}
});