一、明确需求
我希望创建一个web,包含一个表单,能够实现添加任务、完成任务、删除任务等功能,网站具有背景图,通过按钮来进行交互。
二、创建文件
我们需要一个HTML文件、一个CSS样式文件和一个JS文件。
三、开始制作
要创建一个待办事项列表网页,首先需要确定网页的主题和目的。在这个例子中,我们的目标是制作一个用户可以添加和管理待办事项的网页。
接下来,需要设置HTML文档的基本结构。这包括使用`<!DOCTYPE html>`声明文档类型,然后包裹整个网页内容的`<html>`标签,并设置语言属性`lang="en"`表示网页内容是英文。
在`<head>`部分,你需要定义网页的元数据。这包括字符编码`<meta charset="UTF-8">`,确保网页可以显示各种语言的字符;视口设置`<meta name="viewport" content="width=device-width, initial-scale=1.0">`,优化网页在移动设备上的显示效果;以及网页标题`<title>待办事项列表</title>`。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>待办事项列表</title>
<link rel="stylesheet" href="path/your.css">
</head>
为了美化网页,可以链接一个外部CSS文件。这通过在`<head>`标签内添加`<link rel="stylesheet" href="path/your.css">`来实现。
网页的主体内容在`<body>`标签内定义。这里,创建一个容器`<div>`来组织内容,包括一个主标题`<h1>`,一个文本输入框`<input>`供用户输入新的待办事项,一个按钮`<button>`用于添加待办事项,以及一个无序列表`<ul>`来显示待办事项列表。
此外,可以添加一个模态框`<div>`,用于显示额外的信息或提示。模态框内包含一个关闭按钮`<span>`和一个段落`<p>`用于显示文本。
为了实现网页的交互功能,如添加待办事项,需要链接一个外部JavaScript文件。这通过在`<body>`标签的底部添加`<script src="path/your.js"></script>`来实现。
<body>
<div class="container">
<h1>我的待办事项</h1>
<input type="text" id="taskInput" placeholder="添加新任务...">
<button onclick="addTask()">Add</button>
<ul id="taskList"></ul>
<div id="taskModal" class="modal">
<div class="modal-content">
<span class="close">×</span>
<p id="taskText"></p>
</div>
</div>
</div>
<script src="studyjs/study2.js"></script>
</body>
</html>
在CSS文件中,需要定义网页元素的样式,如字体、颜色和布局,以确保网页的外观符合设计要求。
这里就先不具体进行说明,贴上源码:
body {
font-family: 'Arial', sans-serif;
background-image: url('../image/background.jpg');
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
background-attachment: fixed;
margin: 0;
padding: 0;
}
.container {
max-width: 600px;
margin: 50px auto;
padding: 20px;
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
input[type="text"] {
padding: 10px;
width: 70%;
margin-right: 10px;
border: 1px solid #ccc;
border-radius: 4px;
}
button {
padding: 10px 20px;
background-color: #5cb85c;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #4cae4c;
}
ul {
list-style-type: none;
padding: 0;
}
li {
background-color: #fff;
border: 1px solid #ddd;
margin-top: -1px;
padding: 10px;
position: relative;
}
.close {
color: #aaa;
font-size: 28px;
font-weight: bold;
position: absolute;
right: 10px;
top: 0;
cursor: pointer;
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.4);
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
}
.task-actions {
display: flex;
gap: 10px; /* 使用 gap 来保持按钮之间的一致间距 */
}
li {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #fff;
border: 1px solid #ddd;
margin-top: -1px;
padding: 10px;
position: relative;
transition: background-color 0.3s;
}
li.completed {
background-color: #e9e9e9;
text-decoration: line-through;
}
button {
padding: 5px 10px;
border: none;
border-radius: 4px;
cursor: pointer;
}
.complete-btn {
background-color: #4caf50;
}
.complete-btn:hover {
background-color: #45a049;
}
.delete-btn {
background-color: #f44336;
}
.delete-btn:hover {
background-color: #e53935;
}
JavaScript文件中则需要包含处理用户交互的逻辑,如添加待办事项到列表中,或者控制模态框的显示和隐藏。
首先,代码中有一个事件监听器,它在文档完全加载后触发loadTasks()
函数。这个函数的作用是读取保存在浏览器本地存储中的待办事项,并在页面上显示它们。
document.addEventListener('DOMContentLoaded', () => {
loadTasks();
});
接下来是addTask()
函数,它负责将用户输入的新任务添加到待办事项列表中。用户在输入框中输入任务后点击“Add”按钮,这个函数就会被调用。它会创建一个新的列表项(<li>
元素),并将用户输入的任务文本添加到这个列表项中。同时,它还会为每个任务创建两个按钮:一个用于标记任务为完成(“Complete”按钮),另一个用于删除任务(“Delete”按钮)。这些按钮都绑定了相应的事件处理函数,以便用户可以通过点击它们来执行操作。最后,新的任务会被添加到列表的顶部,并保存到本地存储中。
function addTask() {
const taskInput = document.getElementById('taskInput');
const task = taskInput.value.trim();
if (task) {
const li = document.createElement('li');
// 确保新添加的任务默认是未完成的
li.className = "";
const taskText = document.createTextNode(task);
li.appendChild(taskText);
const taskActions = document.createElement('div');
taskActions.className = 'task-actions';
const completeBtn = document.createElement('button');
completeBtn.textContent = 'Complete';
completeBtn.className = 'complete-btn';
completeBtn.onclick = () => toggleComplete(li);
taskActions.appendChild(completeBtn);
const deleteBtn = document.createElement('button');
deleteBtn.textContent = 'Delete';
deleteBtn.className = 'delete-btn';
deleteBtn.onclick = () => deleteTask(li);
taskActions.appendChild(deleteBtn);
li.appendChild(taskActions);
document.getElementById('taskList').insertBefore(li, document.getElementById('taskList').firstChild);
taskInput.value = '';
saveTasks();
}
}
toggleComplete(li)
函数用于切换任务的完成状态。当用户点击“Complete”按钮时,这个函数会被调用。它会检查任务的当前状态,并在任务上添加或移除completed
类,以改变其外观,表示任务已完成或未完成。这个状态的变化也会被保存到本地存储中。
function toggleComplete(li) {
li.classList.toggle('completed');
saveTasks();
}
deleteTask(liElement)
函数用于删除用户不再需要的任务。当用户点击“Delete”按钮时,这个函数会被调用。它会从待办事项列表中移除相应的任务,并更新本地存储中的待办事项列表。
function deleteTask(liElement) {
const taskList = document.getElementById('taskList');
taskList.removeChild(liElement);
saveTasks();
}
saveTasks()
函数是一个关键函数,它负责将当前所有待办事项的状态保存到浏览器的本地存储中。这个函数会遍历待办事项列表中的每个任务,创建一个包含任务文本和完成状态的对象数组,然后将这个数组转换成字符串并保存。这样,即使用户关闭了浏览器窗口,下次打开时仍然可以看到他们之前的任务列表。
function saveTasks() {
const tasks = document.querySelectorAll('#taskList li');
const taskList = [];
tasks.forEach(task => {
taskList.push({ text: task.firstChild.nodeValue, completed: task.classList.contains('completed') });
});
localStorage.setItem('tasks', JSON.stringify(taskList));
loadTasks(); // Reload tasks to sort them
}
最后,loadTasks()
函数在页面加载时被调用,也用于从本地存储中读取待办事项,并在页面上重新显示它们。这个函数会清空现有的任务列表,然后根据本地存储中的数据创建新的任务列表项,并添加到页面上。
function loadTasks() {
const tasks = JSON.parse(localStorage.getItem('tasks')) || [];
const taskList = document.getElementById('taskList');
taskList.innerHTML = ''; // Clear existing tasks
tasks.forEach(task => {
const li = document.createElement('li');
li.className = task.completed ? "completed" : "";
const taskText = document.createTextNode(task.text);
li.appendChild(taskText);
const taskActions = document.createElement('div');
taskActions.className = 'task-actions';
const completeBtn = document.createElement('button');
completeBtn.textContent = 'Complete';
completeBtn.className = 'complete-btn';
completeBtn.onclick = () => toggleComplete(li);
taskActions.appendChild(completeBtn);
const deleteBtn = document.createElement('button');
deleteBtn.textContent = 'Delete';
deleteBtn.className = 'delete-btn';
deleteBtn.onclick = () => deleteTask(li);
taskActions.appendChild(deleteBtn);
li.appendChild(taskActions);
taskList.appendChild(li); // Append to end to keep the order
});
}
完整代码如下:
document.addEventListener('DOMContentLoaded', () => {
loadTasks();
});
function addTask() {
const taskInput = document.getElementById('taskInput');
const task = taskInput.value.trim();
if (task) {
const li = document.createElement('li');
// 确保新添加的任务默认是未完成的
li.className = "";
const taskText = document.createTextNode(task);
li.appendChild(taskText);
const taskActions = document.createElement('div');
taskActions.className = 'task-actions';
const completeBtn = document.createElement('button');
completeBtn.textContent = 'Complete';
completeBtn.className = 'complete-btn';
completeBtn.onclick = () => toggleComplete(li);
taskActions.appendChild(completeBtn);
const deleteBtn = document.createElement('button');
deleteBtn.textContent = 'Delete';
deleteBtn.className = 'delete-btn';
deleteBtn.onclick = () => deleteTask(li);
taskActions.appendChild(deleteBtn);
li.appendChild(taskActions);
document.getElementById('taskList').insertBefore(li, document.getElementById('taskList').firstChild);
taskInput.value = '';
saveTasks();
}
}
function toggleComplete(li) {
li.classList.toggle('completed');
saveTasks();
}
function deleteTask(liElement) {
const taskList = document.getElementById('taskList');
taskList.removeChild(liElement);
saveTasks();
}
function saveTasks() {
const tasks = document.querySelectorAll('#taskList li');
const taskList = [];
tasks.forEach(task => {
taskList.push({ text: task.firstChild.nodeValue, completed: task.classList.contains('completed') });
});
localStorage.setItem('tasks', JSON.stringify(taskList));
loadTasks(); // Reload tasks to sort them
}
function loadTasks() {
const tasks = JSON.parse(localStorage.getItem('tasks')) || [];
const taskList = document.getElementById('taskList');
taskList.innerHTML = ''; // Clear existing tasks
tasks.forEach(task => {
const li = document.createElement('li');
li.className = task.completed ? "completed" : "";
const taskText = document.createTextNode(task.text);
li.appendChild(taskText);
const taskActions = document.createElement('div');
taskActions.className = 'task-actions';
const completeBtn = document.createElement('button');
completeBtn.textContent = 'Complete';
completeBtn.className = 'complete-btn';
completeBtn.onclick = () => toggleComplete(li);
taskActions.appendChild(completeBtn);
const deleteBtn = document.createElement('button');
deleteBtn.textContent = 'Delete';
deleteBtn.className = 'delete-btn';
deleteBtn.onclick = () => deleteTask(li);
taskActions.appendChild(deleteBtn);
li.appendChild(taskActions);
taskList.appendChild(li); // Append to end to keep the order
});
}
当然,这些内容并不完美,仍然可优化。