HTML准备
https://code.jquery.com/
https://materializecss.com/getting-started.html
https://www.bootstrapcdn.com/fontawesome/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<title>Task List</title>
</head>
<body>
<script
src="https://code.jquery.com/jquery-3.5.1.js"
integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc="
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script src="app.js"></script>
</body>
</html>
HTML构造
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<title>Task List</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col s12">
<div id="main" class="card">
<div class="card-content">
<span class="card-title">Task List</span>
<div class="row">
<form id="task-form">
<div class="input-field col s12">
<input type="text" name="task" id="task">
<label for="task">New Task</label>
</div>
<input type="submit" value="Add Task" class="btn">
</form>
</div>
</div>
<div class="card-action">
<h5 id="task-title">Tasks</h5>
<div class="input-field col s12">
<input type="text" name="filter" id="filter">
<label for="filter">Filter tasks</label>
</div>
<ul class="collection"></ul>
<a href="#" class="clear-tasks btn black">Clear Tasks</a>
</div>
</div>
</div>
</div>
<script
src="https://code.jquery.com/jquery-3.5.1.js"
integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc="
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script src="app.js"></script>
</body>
</html>
构造UI——app.js
Add Task功能
(1)form获取表单
(2)tasklist获取ul——要添加行的位置
(3)clearbtn获取clear按钮
(4)filter获取filter的input内容
(5)taskinput获取上半部的task内容;
//Define UI vars
const form = document.querySelector('#task-form');//#id //为整个表单
const taskList = document.querySelector(".collection");//.class //ul
const clearBtn = document.querySelector(".clear-tasks");//clear //a tag
const filter = document.querySelector("#filter"); //filter tasks input
const taskInput = document.querySelector("#task");//task输入框的输入
//Load all event listeners
loadEventListeners();
//Load all event listeners
function loadEventListeners(){
//Add task event
form.addEventListener('submit',addtask); //将submitevent加入form表单
}
function addtask(e){ //定义submitevent
if(taskInput.value ===''){ //若输入为空——弹框(请输入)
alert('Add a task');
}
//Create li element
const li = document.createElement('li');
//Add class
li.className='collection-item'; //存于collectionul中
//Create text node and append to li
li.appendChild(document.createTextNode(taskInput.value));
//Create new link element
const link= document.createElement('a');
//Add class
link.className="delete-item secondary-content";//sc放在最右,在li中加入link (a tag)
//Add icon html
link.innerHTML='<i class="fa fa-remove"></i>'; //x型icon
//Append the link to li
li.appendChild(link);
//Append li to ul
taskList.appendChild(li);
//clear input
taskInput.value="";
console.log(li);
e.preventDefault();
}
获取输入框内容;
构建li,添加输入;
li尾部添加删除按钮;
li添加到下方ul;
清空输入框内容;
加入的标签上的X功能
//Load all event listeners
function loadEventListeners(){
//Add task event
form.addEventListener('submit',addtask); //将submitevent加入form表单
//Remove task event
taskList.addEventListener('click',removetask); //对ul进行设定,继承到i
}
//Remove task
function removetask(e){
//为delgation 需要设定target——ul的i中
if(e.target.parentElement.classList.contains('delete-item')){
if(confirm('Are you sure?')){
//要remove e的parent的parent
e.target.parentElement.parentElement.remove();//即li标签
}
}
e.preventDefault();
}
Clear tasks按钮
两种方法:
(1)将ul的innerHTML内容赋值为“”; (较慢);
(2)while循环清空ul的child;(较快);
//Load all event listeners
function loadEventListeners(){
//Add task event
form.addEventListener('submit',addtask); //将submitevent加入form表单
//Remove task event
taskList.addEventListener('click',removetask); //对ul进行设定,继承到i
//Clear task event
clearBtn.addEventListener('click',cleartasks); //对clearbutton进行设定
}
//Clear tasks
function cleartasks(e){
//taskList.innerHTML=""; //清空ul内容
//Faster
while(taskList.firstChild){ //若有child
taskList.removeChild(taskList.firstChild); //删除
}
e.preventDefault();
}
filter事件
//Load all event listeners
loadEventListeners();
//Load all event listeners
function loadEventListeners(){
//Add task event
form.addEventListener('submit',addtask); //将submitevent加入form表单
//Remove task event
taskList.addEventListener('click',removetask); //对ul进行设定,继承到i
//Clear task event
clearBtn.addEventListener('click',cleartasks); //对clearbutton进行设定
//Filter tasks event
filter.addEventListener('keyup',filtertasks);
}
//Filter Tasks
function filtertasks(e){ //传入e 因为需要得到filtertasks的input内容
const text= e.target.value.toLowerCase(); //得到value转为小写
document.querySelectorAll('.collection-item').forEach((function(task){
const item=task.firstChild.textContent; //得到每个标签的li的textnode
if(item.toLowerCase().indexOf(text)!=-1){ //尝试匹配子字符串 失败返回-1
task.style.display='block'; //显示
}else{
task.style.display='none'; //隐藏
}
}));
//qsa返回一个nodelist,如果用getelebyclas返回htmlcellection,需要转为array
}
上述将UI赋予事件,可执行添加,删除,筛选操作
加入localstorage(添加,删除)
addtask中加入添加至localstorage的操作
在addtask函数中加入对input的存放;
存放函数写在后面;
function addtask(e){ //定义submitevent
if(taskInput.value ===''){
alert('Add a task');
}
//Create li element
const li = document.createElement('li');
//Add class
li.className='collection-item'; //存于collectionul中
//Create text node and append to li
li.appendChild(document.createTextNode(taskInput.value));
//Create new link element
const link= document.createElement('a');
//Add class
link.className="delete-item secondary-content";//sc放在最右,在li中加入link (a tag)
//Add icon html
link.innerHTML='<i class="fa fa-remove"></i>'; //x型icon
//Append the link to li
li.appendChild(link);
//Store in LS
storeTaskInLocalStorage(taskInput.value); //把input的输入加入localstorage
//Append li to ul
taskList.appendChild(li);
//clear input
taskInput.value="";
e.preventDefault(); //submit 需要防止跳转到href
}
//Store Task
function storeTaskInLocalStorage(task){
let tasks;
if(localStorage.getItem('tasks')===null){
tasks=[];
}else{
tasks = JSON.parse(localStorage.getItem('tasks'));
}
tasks.push(task);
localStorage.setItem('tasks',JSON.stringify(tasks));
//存在localstorage中;
}
注意localstorage存取时:
存放要转为JSON.stringify;
取出要转为JSON.parse;
打开页面时调出localstorage的内容
//Load all event listeners
function loadEventListeners(){
//DOM Load event //将存在localstorage的内容提出
document.addEventListener('DOMContentLoaded',gettasks);
//'DOMContentLoaded'在dom被加载后就会执行
//Add task event
form.addEventListener('submit',addtask); //将submitevent加入form表单
//Remove task event
taskList.addEventListener('click',removetask); //对ul进行设定,继承到i
//Clear task event
clearBtn.addEventListener('click',cleartasks); //对clearbutton进行设定
//Filter tasks event
filter.addEventListener('keyup',filtertasks);
}
//Get tasks from LS
function gettasks(){
let tasks;
if(localStorage.getItem('tasks')===null){
tasks=[];
}else{
tasks = JSON.parse(localStorage.getItem('tasks'));
}
tasks.forEach(function(task){ //遍历每一个task——string类型
//Create li element
const li = document.createElement('li');
//Add class
li.className='collection-item'; //存于collectionul中
//Create text node and append to li
li.appendChild(document.createTextNode(task));
//Create new link element
const link= document.createElement('a');
//Add class
link.className="delete-item secondary-content";//sc放在最右,在li中加入link (a tag)
//Add icon html
link.innerHTML='<i class="fa fa-remove"></i>'; //x型icon
//Append the link to li
li.appendChild(link);
//Append li to ul
taskList.appendChild(li);
})
}
在i icon中加入localstorage操作
因为采取array存储;
删除时需要一个一个比对;
且会将每一个同名的都删除;
//Remove task
function removetask(e){
//为delgation 需要设定target——ul的i中
if(e.target.parentElement.classList.contains('delete-item')){
if(confirm('Are you sure?')){
//要remove e的parent的parent
e.target.parentElement.parentElement.remove();//即li标签
//Remove from LS //接在删除操作后
removeTaskFromLocalStorage(e.target.parentElement.parentElement);
}
}
//e.preventDefault();
}
//Remove from LS
function removeTaskFromLocalStorage(taskItem){ //得到被删除的li
let tasks;
if(localStorage.getItem('tasks')===null){
tasks=[];
}else{
tasks = JSON.parse(localStorage.getItem('tasks'));
}
tasks.forEach(function(task,index){
if(taskItem.textContent===task){ //找到要删除的task
tasks.splice(index,1); //在array中删除该元素
} //bug——若有同名内容也会一并删除
});
localStorage.setItem('tasks',JSON.stringify(tasks)); //重新赋给tasks
}
CLear tasks 清屏加入localstorage
调用函数——localstorage.clear();
//Clear tasks
function cleartasks(){
//taskList.innerHTML=""; //清空ul内容
//Faster
while(taskList.firstChild){ //若有child
taskList.removeChild(taskList.firstChild); //删除
}
//e.preventDefault();
//Clear from LS
claerTasksFromLocalStroage();
}
//Clear tasks from LS
function claerTasksFromLocalStroage(){
localStorage.clear();
}
完整代码
//Define UI vars
const form = document.querySelector('#task-form');//#id //为整个表单
const taskList = document.querySelector(".collection");//.class //ul
const clearBtn = document.querySelector(".clear-tasks");//clear //a tag
const filter = document.querySelector("#filter"); //filter tasks input
const taskInput = document.querySelector("#task");//task输入框的输入
//Load all event listeners
loadEventListeners();
//Load all event listeners
function loadEventListeners(){
//DOM Load event //将存在localstorage的内容提出
document.addEventListener('DOMContentLoaded',gettasks);
//'DOMContentLoaded'在dom被加载后就会执行
//Add task event
form.addEventListener('submit',addtask); //将submitevent加入form表单
//Remove task event
taskList.addEventListener('click',removetask); //对ul进行设定,继承到i
//Clear task event
clearBtn.addEventListener('click',cleartasks); //对clearbutton进行设定
//Filter tasks event
filter.addEventListener('keyup',filtertasks);
}
//Get tasks from LS
function gettasks(){
let tasks;
if(localStorage.getItem('tasks')===null){
tasks=[];
}else{
tasks = JSON.parse(localStorage.getItem('tasks'));
}
tasks.forEach(function(task){ //遍历每一个task——string类型
//Create li element
const li = document.createElement('li');
//Add class
li.className='collection-item'; //存于collectionul中
//Create text node and append to li
li.appendChild(document.createTextNode(task));
//Create new link element
const link= document.createElement('a');
//Add class
link.className="delete-item secondary-content";//sc放在最右,在li中加入link (a tag)
//Add icon html
link.innerHTML='<i class="fa fa-remove"></i>'; //x型icon
//Append the link to li
li.appendChild(link);
//Append li to ul
taskList.appendChild(li);
})
}
function addtask(e){ //定义submitevent
if(taskInput.value ===''){
alert('Add a task');
}
//Create li element
const li = document.createElement('li');
//Add class
li.className='collection-item'; //存于collectionul中
//Create text node and append to li
li.appendChild(document.createTextNode(taskInput.value));
//Create new link element
const link= document.createElement('a');
//Add class
link.className="delete-item secondary-content";//sc放在最右,在li中加入link (a tag)
//Add icon html
link.innerHTML='<i class="fa fa-remove"></i>'; //x型icon
//Append the link to li
li.appendChild(link);
//Store in LS
storeTaskInLocalStorage(taskInput.value); //把input的输入加入localstorage
//Append li to ul
taskList.appendChild(li);
//clear input
taskInput.value="";
e.preventDefault(); //submit 需要防止跳转到href
}
//Store Task
function storeTaskInLocalStorage(task){
let tasks;
if(localStorage.getItem('tasks')===null){
tasks=[];
}else{
tasks = JSON.parse(localStorage.getItem('tasks'));
}
tasks.push(task);
localStorage.setItem('tasks',JSON.stringify(tasks));
//存在localstorage中;
}
//Remove task
function removetask(e){
//为delgation 需要设定target——ul的i中
if(e.target.parentElement.classList.contains('delete-item')){
if(confirm('Are you sure?')){
//要remove e的parent的parent
e.target.parentElement.parentElement.remove();//即li标签
//Remove from LS //接在删除操作后
removeTaskFromLocalStorage(e.target.parentElement.parentElement);
}
}
//e.preventDefault();
}
//Remove from LS
function removeTaskFromLocalStorage(taskItem){ //得到被删除的li
let tasks;
if(localStorage.getItem('tasks')===null){
tasks=[];
}else{
tasks = JSON.parse(localStorage.getItem('tasks'));
}
tasks.forEach(function(task,index){ //获取遍历时的index
if(taskItem.textContent===task){ //找到要删除的task
tasks.splice(index,1); //在array中删除该元素
} //bug——若有同名内容也会一并删除
});
localStorage.setItem('tasks',JSON.stringify(tasks)); //重新赋给tasks
}
//Clear tasks
function cleartasks(){
//taskList.innerHTML=""; //清空ul内容
//Faster
while(taskList.firstChild){ //若有child
taskList.removeChild(taskList.firstChild); //删除
}
//e.preventDefault();
//Clear from LS
claerTasksFromLocalStroage();
}
//Clear tasks from LS
function claerTasksFromLocalStroage(){
localStorage.clear();
}
//Filter Tasks
function filtertasks(e){ //传入e 因为需要得到filtertasks的input内容
const text= e.target.value.toLowerCase(); //得到value转为小写
document.querySelectorAll('.collection-item').forEach((function(task){
const item=task.firstChild.textContent; //得到每个标签的li的textnode
if(item.toLowerCase().indexOf(text)!=-1){ //尝试匹配子字符串 失败返回-1
task.style.display='block'; //显示
}else{
task.style.display='none'; //隐藏
}
}));
//qsa返回一个nodelist,如果用getelebyclas返回htmlcellection,需要转为array
}