互联网建立在与数据交互的基础上:从用户获取数据、存储数据、更新和删除数据。待办事项应用程序是练习这些基本技能的最佳工具。
在本教程中,我们将介绍如何使用 HTML、CSS 和 JavaScript 创建功能齐全的待办事项应用程序。用户将能够执行以下操作:
我们的 HTML 将包含三个部分:
ul 元素是空的,因为我们将在其中使用 JavaScript 动态添加任务。每个任务将包含以下元素:
我们将从主体样式开始,以确保所有元素水平居中:
包含所有部分的容器元素将具有以下样式:
接下来设置消息部分的样式,以确保它始终位于容器元素的中心。
对于搜索框部分,使用 Flexbox 确保子元素居中对齐且间隔均匀。
对于输入,添加以下样式:
为了确保我们的任务垂直堆叠,请将 flex-direction 设置为 column,并添加一些填充和边距以确保各个任务之间的空间。
使用 flex-basis 确保用于显示任务的 span 元素占据宽度的 60%,而按钮仅占据 20%。
去掉默认的按钮样式,并在编辑和删除按钮上添加透明背景,以确保图标可见:
将以下样式添加到图标中
对于单选按钮,我们将具有以下自定义样式:
最后,添加这些样式,这些样式将使用 JavaScript 动态添加。
现在我们的应用程序看起来像这样:
为了让用户能够添加任务,我们将使用 JavaScript。让我们首先使用 DOM(文档对象模型)获取以下 HTML 元素:
接下来,让我们初始化一些变量:
该变量html
将存储包含代表每个任务的 HTML 标记的 html 字符串。
该allTasks
数组将存储所有任务,每个任务都有一个 id(时间戳)、一个名称和一个完成值,该值可以是 true 或 false。示例任务如下所示:
好吧,首先向添加任务按钮添加单击事件侦听器。在事件侦听器函数中,我们将从用户获取输入值,将其传递给函数addTask()
,并将输入值设置为空字符串。
如果用户没有输入值,我们将返回:这将防止在用户没有输入任何值时向列表中添加空任务或执行不必要的操作
定义addTask()
函数。
在函数内部,我们想要执行以下操作:
allTasks
数组中html
到ulElement
更新函数如下。
正如您所看到的,代表任务的每个 li 元素都有一个作为数据属性值添加的唯一 id ( data-id = ${taskId}
):这将允许我们在编辑或删除任务时检索 id。
定义一个函数,名为removeTask()
在函数内部removeTask()
,我们想要获取 li 元素的 data 属性并从 DOM 中删除任务。
让我们分解一下removeTask()
函数中发生了什么。
querySelectorAll
属性来选择所有按钮。this.closest("li)
(其中 this 指的是单击的按钮)。liElement
然后我们从 DOM 中删除。taskId
。我们在实现本地存储时会用到这个值定义一个名为 的函数editTask()
。在这个函数中,我们想要执行与删除按钮相同的步骤:即:
forEach()
方法迭代并获取最接近的li
元素allTasks
使用 id 在数组中查找任务更新editTask()
函数如下:
让我们分解一下editTask()
上面函数中发生的事情:
findIndex()
方法检查该 id 是否存在于allTaksks
数组中。findIndex()
方法查找满足指定条件的第一个元素的索引。如果没有找到元素,则返回-1taskIndex
不是-1,我们使用该taskIndex
值来获取当前任务,代码如下allTasks[taskIndex].task
const newTask = prompt("Edit Task", currentTask);
:显示一个提示对话框,其中包含消息“编辑任务:”,并将输入值设置为当前任务内容(currentTask
)。 newTask
变量中。allTasks[taskIndex].task = newTask
:更新数组中的新任务名称。contentElement.textContent = new Task;
现在,如果您单击任何任务的编辑按钮,您应该会看到此提示。
要将任务标记为完成,我们将以下 CSS 类应用于单选按钮和 li 元素中的内容。
创建completeTask()
函数,如下所示:
在该completeTask()
函数中,我们执行以下操作:
findIndex()
方法从数组中获取当前任务的索引allTasks
,然后将按钮的状态更新为选中。即使添加任务后,刷新页面后它们也会消失。为了持久存储,我们将添加本地存储功能。
本地存储是一个允许您在浏览器中存储数据的对象。数据以键值对的字符串形式存储。即使关闭浏览器后,存储在浏览器中的数据仍然存在。只有清除缓存后,它才会被删除。
将此功能添加到我们的项目中将允许添加的数据即使在刷新或关闭页面后也能保留。 要将数据存储在本地存储中,可以使用 setItem,如下所示。
存储此数据后,使用 Chrome 开发工具,您可以在“应用程序”选项卡下看到这些数据。
要获取存储在本地存储中的项目,请使用以下密钥:
从本地存储中删除项目
让我们实现在本地存储中添加任务的功能。由于我们已经拥有数组中的所有任务allTasks
,因此我们需要做的就是将数据添加到本地存储中,如下所示:
由于本地存储中存储的数据是字符串格式,因此我们习惯JSON.stringify
将任务对象转换为字符串进行存储。
更新addTask()
函数如下:
现在返回并添加一些任务,您应该在浏览器中看到它们。
我们还需要从本地存储加载任务。创建一个名为 的函数loadFromStorage()
。该函数将检查本地存储中是否有任务,如果找到,任务将使用该函数呈现在页面上renderTasks()
。
创建该renderTasks()
函数并添加以下代码。
让我们分解一下该renderTasks()
函数的作用:
`
forEach()
方法迭代allTasks
数组并将每个任务的 HTML 标记添加到ulElement
.const completedClass=task.completed? "complete strike-through": "":
是一个条件,用于检查是否task.completed
为 true 并添加“完整删除线”CSS 类。如果task.completed
为 false,则不会应用 CSS 类。要更新本地存储中的任务,请更新editTask()
函数如下:
该行将localStorage.setItem("tasks",JSON.stringify(allTasks);
确保任务更新后更新任务的当前状态。
要从本地存储中删除任务,请创建一个deleteTask()
函数并添加以下代码;
在deleteTask()
上面的函数中,我们使用任务的 id 来检查它是否存在于数组中allTasks
。如果找到,我们使用该splice()
方法从数组中删除该任务allTasks
。
更新removeTasks()
函数如下:
最后要做的事情是,如果用户没有待处理的任务,则向用户显示一条消息: