原生js实现todolist功能

本文详细介绍了如何使用HTML、CSS和JavaScript实现一个简单的TodoList应用,包括添加任务、删除、标记完成和存储功能。通过localStorage实现数据持久化,适合初级开发者学习前端交互设计。
摘要由CSDN通过智能技术生成

效果图:
在这里插入图片描述
上代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>todolist</title>
		<style type="text/css">
			body {
				margin: 0;
				padding: 0;
				font-size: 16px;
				background: #CDCDCD;
			}

			header {
				height: 50px;
				background: #333;
				background: rgba(47, 47, 47, 0.98);
			}

			section {
				margin: 0 auto;
			}

			label {
				float: left;
				width: 100px;
				line-height: 50px;
				color: #DDD;
				font-size: 24px;
				cursor: pointer;
				font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
			}

			header input {
				float: right;
				width: 60%;
				height: 24px;
				margin-top: 12px;
				text-indent: 10px;
				border-radius: 5px;
				box-shadow: 0 1px 0 rgba(255, 255, 255, 0.24), 0 1px 6px rgba(0, 0, 0, 0.45) inset;
				border: none
			}

			input:focus {
				outline-width: 0
			}

			h2 {
				position: relative;
			}

			span {
				position: absolute;
				top: 2px;
				right: 5px;
				display: inline-block;
				padding: 0 5px;
				height: 20px;
				border-radius: 20px;
				background: #E6E6FA;
				line-height: 22px;
				text-align: center;
				color: #666;
				font-size: 14px;
			}

			ol,
			ul {
				padding: 0;
				list-style: none;
			}

			li input {
				position: absolute;
				top: 2px;
				left: 10px;
				width: 22px;
				height: 22px;
				cursor: pointer;
			}

			p {
				margin: 0;
			}

			li p input {
				top: 3px;
				left: 40px;
				width: 70%;
				height: 20px;
				line-height: 14px;
				text-indent: 5px;
				font-size: 14px;
			}

			li {
				height: 32px;
				line-height: 32px;
				background: #fff;
				position: relative;
				margin-bottom: 10px;
				padding: 0 45px;
				border-radius: 3px;
				border-left: 5px solid #629A9C;
				box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07);
			}

			ol li {
				cursor: move;
			}

			ul li {
				border-left: 5px solid #999;
				opacity: 0.5;
			}

			li a {
				position: absolute;
				top: 2px;
				right: 5px;
				display: inline-block;
				width: 14px;
				height: 12px;
				border-radius: 14px;
				border: 6px double #FFF;
				background: #CCC;
				line-height: 10px;
				text-decoration: none;
				text-align: center;
				color: #FFF;
				font-weight: bold;
				font-size: 14px;
				cursor: pointer;
			}

			footer {
				color: #666;
				font-size: 14px;
				text-align: center;
			}

			footer a {
				color: #666;
				text-decoration: none;
				color: #999;
			}

			@media screen and (max-device-width: 620px) {
				section {
					width: 96%;
					padding: 0 2%;
				}
			}

			@media screen and (min-width: 620px) {
				section {
					width: 600px;
					padding: 0 10px;
				}
			}
		</style>
	</head>
	<body>
		<header>
			<section>
				<form action="" id="form" onclick="">
					<label for="title">ToDoList</label>
					<input type="text" id="title" name="title" placeholder="添加ToDo" required="required"
						autocomplete="off" />
				</form>
			</section>
		</header>
		<section>
			<h2>正在进行 <span id="todocount"></span></h2>
			<ol id="todolist" class="demo-box">
			</ol>
			<h2>已经完成 <span id="donecount"></span></h2>
			<ul id="donelist">
			</ul>
		</section>
		<footer>
			Copyright &copy; 2014 todolist.cn <a href="javascript:clear();">clear</a>
		</footer>
		<script type="text/javascript">
			window.onload = function() {
				var form = document.querySelector('form'),
					tle = document.querySelector('#title'),
					ol = document.querySelector('#todolist'),
					ul = document.querySelector('#donelist'),
					todocount = document.querySelector('#todocount'),
					donecount = document.querySelector('#donecount');
				load();
				tle.addEventListener('keydown', function(e) {
					e = e || window.event;
					if (e.keyCode) {
						if (e.keyCode == 13) {
							if (this.value.length == 0) {
								return;
							} else {
								// login();
								//先读取本地存储原来的数据
								var local = getDate();
								//把local数组进行更新数据,把最新的数据追加到local数组中
								local.push({
									title: this.value,
									done: false
								});
								//把这个数组local 存储给本地储存
								saveDate(local);
								//重置表单
								form.reset();
								//把本地存储熏染到加载页面当中
								load();
								//输入完成后清空文本框
								this.value = '';
							}
						}
					}
				}, false)

				// 删除操作
				function removetdlist(obj) {
					var as = obj.querySelectorAll('a');
					/* console.log(as); */
					for (var j = 0; j < as.length; j++) {
						as[j].onclick = function() {
							//先获取本地存储
							var data = getDate();
							//修改数据
							var index = this.id;
							// console.log(index);
							data.splice(index, 1);
							//保存到本地存储
							saveDate(data);
							//重新熏染页面
							load();
						}
					}
				}

				// 正在进行和已完成操作
				function changeDate(obj) {
					obj.addEventListener('click', function(e) {
						e = e || window.event;
						if (e.target.className === 'change') {
							var index = e.target.nextElementSibling.nextElementSibling.id;
							// console.log(index);
							//修改done的属性值
							var data = getDate();
							data[index].done = e.target.checked;
							/* console.log(data); */
							//保存到本地存储
							saveDate(data);
							//重新熏染页面
							load()
						}
					}, false)
				}
				//函数调用重新熏染加载页面
				changeDate(ol);
				changeDate(ul);

				//编辑修改
				function edit() {
					//双击监听事件
					ol.addEventListener('dblclick', function(e) {
						e = e || window.event;
						if (e.target.nodeName === "P") {
							var id = e.target.getAttribute('id'); //获取id
							var p = document.getElementById(id); //获取 li p 元素 
							var title = p.innerHTML;
							//双击到p标签添加子节点input
							p.innerHTML = "<input type='text' value='" + title + "' id='data" + id + "'/>"

							var input = document.getElementById('data' + id);
							// console.log(input);
							input.select(); //文本框里面的文字处于选定状态
							//失去焦点的时候
							input.onblur = function() {
								if (input.value != '') {
									p.innerHTML = input.value; //把input的value值赋值给p.innerHTML存储新的p.innerHTML
									var index = id.substring(0) //获取当前修改的索引值
									// console.log(index);
									// //先获取本地存储
									var data = getDate();
									//修改数据
									data[index].title = this.value;
									// //保存到本地存储
									saveDate(data); //存储新的p.innerHTML
									// //重新熏染页面
									load();
								} else {
									return;
								}
							}
							//按下回车键也可以把文本框里面的值给p
							input.addEventListener('keyup', function(e) {
								if (e.keyCode === 13) {
									//手动调用表单失去焦点事件 不需要鼠标离开操作
									this.blur();

								}
							}, false)
						}
					}, false)
				}
				edit()

				//读取本地存储的数据
				function getDate() {
					var data = localStorage.getItem("todolist");
					if (data !== null) {
						return JSON.parse(data);
					} else {
						return [];
					}
				}

				//保存本地存储数据
				function saveDate(data) {
					localStorage.setItem("todolist", JSON.stringify(data));
				}

				//熏染加载数据
				function load() {
					//读取本地存储数据
					var data = getDate();
					//遍历之前先要清空ol里面的元素内容
					ol.innerHTML = '';
					ul.innerHTML = '';
					/* var childs = ol.childNodes;
					for (var i = childs.length - 1; i >= 0; i--) {
					    ol.removeChild(childs[i]);
					} */
					//正在进行的个数
					var todoCount = 0;
					//已经完成的个数
					var doneCount = 0;
					//遍历数据
					data.forEach(function(element, index) {
						var li = document.createElement('li');
						li.innerHTML =
							"<input type='checkbox' class='change'/><p id=" + index + ">" +
							element
							.title +
							"</p><a href='javascript:;' id=" + index + ">-</a>";
						if (element.done) {
							ul.insertBefore(li, ul.children[0]);
							li.children[0].checked = 'checked'
							doneCount++;
						} else {
							ol.appendChild(li);
							todoCount++;
						}
					});
					removetdlist(ol);
					removetdlist(ul);
					//任务进行个数
					todocount.innerHTML = todoCount;
					//任务完成个数
					donecount.innerHTML = doneCount;
				}
			}
		</script>
	</body>
	</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值