目录
前言
界面比较简陋,实现了本地存储,刷新不会损失数据,可以定时提醒,并添加了三个动画。代码还有很多不足之处,应该可以写得更精简的,详情请看代码。
HTML部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="todoList.css" />
<link rel="stylesheet" href="iconfont.css" />
<script src="todoList.js" ></script>
</head>
<body>
<div class="all">
<div class="kkl"></div>
<div class="add">
<div class="combine">
<div class="cephalic">
<span class="iconfont" id="logo"></span>
<span class="headline">任务</span>
</div>
<div class="task">
<ul class="todo-list" id="todolist"></ul>
<div class="com">
<div class="store" style="cursor: pointer;">
<span>已完成</span><i class="iconfont" id="vue"></i>
</div>
<ul class="todo-com"> </ul>
</div>
</div>
<div class="join">
<from class="from">
<button class="submit">
<span class="iconfont" id="submit_add"></span>
</button>
<div class="from-input">
<input placeholder="添加任务" id="content">
</div>
</from>
</div>
</div>
</div>
<div class="warn" id="div">
<img src="m1.gif" >
</div>
<div class="contet">
<div id="rainBox"></div>
</div>
<div class="sup" id="sup">
<div class="hint" id="hint"></div>
<img src="c1.gif" id="nv">
</div>
</div>
</body>
</html>
CSS部分
* {
margin: 0px;
padding: 0px;
list-style-type: none;
}
html,
body {
width: 100%;
height: 100%;
overflow-x: hidden;
}
body {
background-image: linear-gradient(90deg, #bedc98, #84e4a6);
}
.all {
display: flex;
width: 100%;
position: relative;
height: 100%;
}
.add {
display: table;
border-radius: 30px;
background-color: #ffffff;
width: 520px;
height: 550px;
position: relative;
margin-top: 80px;
margin-left: auto;
margin-right: auto;
}
.combine {
position: relative;
margin: auto;
margin-top: 35px;
width: 400px;
}
.cephalic {
width: 398px;
height: 50px;
display: flex;
margin-bottom: 30px;
}
#logo {
margin-top: 2px;
font-size: 40px;
color: rgb(142, 135, 135);
text-align: center;
}
.headline {
margin-left: 10px;
margin-top: 5px;
font-size: 30px;
font-family: "Times New Roman", Times, serif;
text-align: center;
font-weight: 700;
color: rgb(156, 149, 149);
}
.task {
height: 350px;
overflow: auto;
}
.press-sel {
outline: none;
position: relative;
border: none;
background-color: transparent;
}
.todo-list li {
text-overflow: ellipsis;
border-radius: 15px;
display: flex;
font-size: 20px;
color: rgb(255, 255, 255);
height: 45px;
margin-bottom: 20px;
background-color: #84b5a0;
}
.todo-list li {
margin-left: 18px;
font-size: 23px;
text-overflow: ellipsis;
font-weight: 600;
color: rgb(255, 255, 255);
}
.todo-com li {
text-overflow: ellipsis;
border-radius: 15px;
display: flex;
font-size: 20px;
color: rgb(255, 255, 255);
height: 45px;
margin-bottom: 20px;
background-color: #4a4a4a46;
}
.todo-com li {
margin-left: 18px;
font-size: 23px;
text-overflow: ellipsis;
font-weight: 600;
color: rgb(255, 255, 255);
}
.content {
margin-top: 9px;
width: 250px;
margin-left: 10px;
text-overflow: ellipsis;
overflow: hidden;
font-family: Arial, Helvetica, sans-serif;
}
.del {
color: rgb(255, 255, 255);
font-size: 23px;
float: right;
position: absolute;
margin-left: 40px;
font-weight: 700;
margin-top: 10px;
}
.sel {
color: rgb(255, 255, 255);
font-size: 23px;
margin-left: 10px;
float: right;
font-weight: 700;
}
.press-del {
display: flex;
position: relative;
border: none;
background-color: transparent;
}
.join {
height: 35px;
border-radius: 10px;
margin-top: 8px;
}
.from {
display: flex;
}
.submit {
margin-top: 2px;
border: none;
background-color: transparent;
}
#submit_add {
color: #6c6363;
font-size: 30px;
margin-left: 10px;
}
.from-input {
margin: 10px;
}
#content {
font-size: 18px;
background-color: transparent;
border: none;
outline: none;
height: 32px;
width: 300px;
color: #878484;
border-bottom: 3px dashed #84b5a0;
}
.task::-webkit-scrollbar {
/*滚动条整体样式*/
width: 3px; /*高宽分别对应横竖滚动条的尺寸*/
height: 1px;
}
.task::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
background-color: rgb(228, 228, 228);
}
.task::-webkit-scrollbar-track {
/*滚动条里面轨道*/
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
background: #ededed;
border-radius: 10px;
}
input::placeholder {
color: rgb(223, 223, 223);
opacity: 1;
}
.store {
width: 120px;
color: #4a4a4a46;
background-color: #66666621;
font-size: 20px;
font-weight: 700;
margin-left: 15px;
height: 35px;
border-radius: 15px;
margin-bottom: 20px;
display: flex;
}
.store span {
display: block;
margin-top: 3px;
margin-left: 15px;
}
.store i {
display: block;
margin-top: 6px;
margin-left: 10px;
}
.epo {
margin-top: 10px;
color: rgb(255, 255, 255);
font-size: 23px;
margin-right: 10px;
font-weight: 700;
}
.timer {
position: absolute;
margin-left: 30px;
margin-top: -35px;
height: 80px;
width: 60px;
z-index: 1;
display: none;
border-radius: 30px !important;
}
.timer span {
width: 60px;
height: 25px;
border-radius: 5px;
background-color: rgb(116, 141, 121);
font-size: 16px;
display: block;
color: #ffffff;
border: #1b892dfa solid 1px;
}
.timer span:hover {
background-color: bisque;
}
.warn {
position: absolute;
}
.warn img {
width: 260px;
}
.contet {
position: relative;
}
#rainBox {
position: fixed;
top: 0px;
left: 0;
width: 100%;
height: 100%;
/* 不阻挡其它事件 */
pointer-events: none;
}
.rain {
position: absolute;
width: 1px;
height: 30px;
background: linear-gradient(
rgba(255, 255, 255, 0.6),
rgba(255, 255, 255, 0.9)
);
}
.sup {
position: fixed;
right: 0px;
bottom: 10px;
}
#nv {
width: 240px;
}
.hint {
display: none;
overflow: hidden;
height: 25px;
background-color: rgba(166, 254, 150, 0.58);
width: 210px;
border-radius: 30px;
margin-left: 25px;
font-size: 20px;
font-weight: 600;
text-align: center;
color: rgb(228, 121, 67);
}
.content title{
position: absolute;
color: #ffffff;
font-size: 14px;
padding: 4px;
background: rgba(40, 40, 40, 0.8);
border-radius:5px;
z-index:999;
}
JS部分
代码比较杂,写得比较繁琐,不过简单易懂,作为新手也是可以看懂的,基本上每个代码都有注释。添加事件使用的是字符串,比较简单,一直拼接字符串,然后使用innerHTML进行渲染。
window.onload = function () {
let todoList = document.getElementsByClassName("todo-list")[0];
let newInput = document.querySelector("#content");
let todoCom = document.getElementsByClassName("todo-com")[0];
let Hint = document.getElementsByClassName("hint")[0];
load();
//存储input里的内容
newInput.onkeydown = function (event) {
if (event.keyCode === 13 && newInput.value !== "") {
var local = getData();
//存储格式
local.push({ title: newInput.value, done: false });
savaDate(local);
load();
}
};
//读取本地储存
function getData() {
var data = localStorage.getItem("todolist");
if (data !== null) {
// JSON.parse() 将一个 JSON 字符串转换为 JavaScript 对象
return JSON.parse(data);
} else {
return [];
}
}
//保存本地数据
function savaDate(data) {
// JSON.stringify() 将 JavaScript 值转换为 JSON 字符串
localStorage.setItem("todolist", JSON.stringify(data));
}
//渲染加载数据
function load() {
//读取本地数据
var data = getData();
var str = "";
var stv = "";
//遍历数据,拼接字符串
data.forEach((event, index) => {
if (event.done === false) {
str =
'<li class="record-item"> ' +
'<button class="press-sel">' +
'<i class="iconfont sel" id="' +
index +
'"></i>' +
"</button>" +
'<p class="content" title=' +
event.title +
">" +
event.title +
"</p>" +
'<button class="press-del">' +
'<i class="iconfont epo" id="' +
index +
'" style="cursor: pointer;">' +
'<div class="timer" id="' +
index +
'"><span class="second" id="' +
index +
'">5s</span><span class="hour" id="' +
index +
'">1h</span><span class="day" id="' +
index +
'">1d</sapn></div></i>' +
'<i class="iconfont del" id="' +
index +
'" style="cursor: pointer;"></i>' +
"</li>" +
str;
} else {
stv =
'<li class="record-ite"> ' +
'<button class="press-sel">' +
'<i class="iconfont sel" id="' +
index +
'"></i>' +
"</button>" +
'<p class="content" title=' +
event.title +
" ><s>" +
event.title +
"</s></p>" +
'<button class="press-del">' +
'<i class="iconfont del" id="' +
index +
'" style="cursor: pointer;"></i>' +
"</li>" +
stv;
}
});
//遍历之前清空ul里的元素内容·
newInput.value = "";
//渲染内容到HTML
todoList.innerHTML = str;
todoCom.innerHTML = stv;
//删除的方法
del();
//完成的方法
sel();
//收拢的方式
store();
//完成隐藏
com();
console.log(timers);
//提醒事件
timers();
//提醒时间
second();
hour();
day();
//雨点
// rain();
//拖动
drag();
sup();
}
//删除操作
function del() {
var del = document.querySelectorAll(".del");
// console.log(del);
if (del !== "") {
del.forEach((element) => {
element.onclick = function () {
//本地读取
var data = getData();
//修改数据
var index = element.getAttribute("id");
data.splice(index, 1);
//保存本地
savaDate(data);
//渲染
load();
};
});
}
}
//完成
function sel() {
var sel = document.querySelectorAll(".sel");
if (sel !== "") {
sel.forEach((element) => {
element.onclick = function () {
//本地读取
var data = getData();
//修改数据
//获得索引
var index = element.getAttribute("id");
// console.log(data[index].done);
//修改数组
if (data[index].done === false) {
//下雨庆祝
rain();
data.splice(index, 1, { title: data[index].title, done: true });
} else {
data.splice(index, 1, { title: data[index].title, done: false });
}
//保存本地
savaDate(data);
//渲染
load();
};
});
}
}
//完成收拢
function store() {
var store = document.querySelectorAll(".store");
var vue = document.getElementById("vue");
store.forEach((element) => {
element.onclick = function () {
if (todoCom.style.display == "none") {
todoCom.style.display = "block";
vue.innerHTML = "";
} else {
todoCom.style.display = "none";
vue.innerHTML = "";
}
};
});
}
//完成隐藏
function com() {
let Com = document.querySelectorAll(".com");
Com.forEach((element) => {
if (todoCom.innerHTML == "") {
element.style.display = "none";
} else {
element.style.display = "block";
}
});
}
//提醒事件
function timers() {
var epo = document.querySelectorAll(".epo");
console.log(epo);
epo.forEach((element) => {
var isShow = false;
var time;
element.onclick = function () {
clearTimeout(time);
if (!isShow) {
isShow = true;
element.childNodes[1].style.display = "block";
} else {
isShow = false;
element.childNodes[1].style.display = "none";
}
//鼠标移入事件
element.onmouseover = () => {
clearTimeout(time);
};
//鼠标移出事件
element.onmouseout = () => {
clearTimeout(time);
//计时器更改属性
if (isShow) {
time = setTimeout(() => {
element.childNodes[1].style.display = "none";
isShow = false;
}, 400);
}
};
};
});
}
//计时5s
function second() {
let second1 = document.querySelectorAll(".second");
// let hint=document.getElementById("hint");
second1.forEach((element) => {
element.onclick = function () {
//本地读取
var data = getData();
var index = element.getAttribute("id");
var time;
var stv = "";
console.log(index);
clearTimeout(time);
time = setTimeout(function () {
Hint.style.display = "block";
stv = data[index].title;
Hint.innerHTML = stv;
// alert("任务`"+data[index].title+"`时间到啦");
}, 5000);
};
});
}
//计时1小时
function hour() {
let hour = document.querySelectorAll(".hour");
hour.forEach((element) => {
element.onclick = function () {
//本地读取
var data = getData();
var stv = "";
var index = element.getAttribute("id");
var time;
clearTimeout(time);
time = setTimeout(function () {
// alert("任务`"+data[index].title+"`时间到啦")
Hint.style.display = "block";
stv = data[index].title;
Hint.innerHTML = stv;
}, 60 * 1000 * 60);
};
});
}
//计时一天
function day() {
let day = document.querySelectorAll(".day");
day.forEach((element) => {
element.onclick = function () {
//本地读取
var data = getData();
var index = element.getAttribute("id");
var time;
var stv = "";
// console.log(index)
clearTimeout(time);
time = setTimeout(function () {
Hint.style.display = "block";
stv = data[index].title;
Hint.innerHTML = stv;
}, 1000 * 60 * 60 * 24);
};
});
}
//下雨事件
function rain() {
const box = document.getElementById("rainBox");
var time;
//每隔一段时间添加雨点
time = setInterval(() => {
// clearInterval(timer)
let boxHeight = box.clientHeight;
let boxWidth = box.clientWidth;
const rain = document.createElement("div");
rain.classList.add("rain");
rain.style.top = 0;
//随机刷新雨点位置
rain.style.left = Math.random() * boxWidth + "px";
//随机雨点透明度
rain.style.opacity = Math.random();
box.appendChild(rain);
//每隔一段时间雨点下落
let race = 1;
const timer = setInterval(() => {
if (parseInt(rain.style.top) > boxHeight) {
clearInterval(timer);
box.removeChild(rain);
}
race++;
rain.style.top = parseInt(rain.style.top) + race + "px";
}, 1);
}, 1);
setInterval(() => {
clearTimeout(time);
}, 10000);
}
//小猫
function drag() {
var isShow = false;
let div = document.getElementById("div");
let body;
setInterval(() => {
// 获取整个网页的宽度
body = document.body.scrollWidth;
// console.log(body)
div.onclick = function () {
if (body === 1490) {
if (!isShow) {
isShow = true;
} else {
isShow = false;
}
if (isShow) {
// onmousemove鼠标指针移到指定的对象时发生
document.onmousemove = function (e) {
let event = e || window.event;
//解决兼容问题,获得鼠标位置
div.style.left = event.clientX - div.clientWidth / 2 + "px";
};
} else {
document.onmousemove = function (e) {
let event = e || window.event;
//解决兼容问题,获得鼠标位置
div.style.left = div.style.left;
};
}
}
};
}, 100);
}
//超人
function sup() {
var isShow = false;
let sup = document.getElementById("sup");
var num = 0;
sup.onclick = function () {
//隐藏提醒框
Hint.style.display = "none";
let speed = 15;
if (!isShow) {
isShow = true;
} else {
isShow = false;
}
if (isShow) {
timer = setInterval(() => {
num += speed;
// 获取整个网页的高度
let body = document.body.scrollHeight;
sup.style.bottom = num + "px";
if (num >= body) {
num = -250;
}
}, 100);
} else {
//结束计时
clearInterval(timer);
num = num;
}
};
}
};