Skip to content

简单待办列表

中等约 30 分钟

你将构建什么

一个待办列表应用:输入框添加新待办,列表显示所有待办,每条可以标记完成(划线效果)或删除。用数组管理数据,DOM 根据数据动态渲染。

学习目标

  • 用数组管理待办数据,DOM 根据数据渲染
  • 实现添加、标记完成、删除三种操作
  • 用事件委托处理列表项的交互
  • 理解数据驱动 UI 的基本模式

前置要求

  • 了解 JavaScript 数组方法(push、filter、map)
  • 了解 DOM 操作和事件监听
  • 已完成前四个 JS 项目或具备同等基础

步骤

  1. 1

    搭建界面骨架

    HTML 中放输入框、添加按钮、待办列表容器。列表用 ul,初始为空。

    代码
    <input type="text" id="todo-input" placeholder="输入待办内容..." />
    <button id="add-btn">添加</button>
    <ul id="todo-list"></ul>

    预期结果

    页面显示输入框、按钮和空列表。

  2. 2

    管理待办数据

    用数组 todos 管理数据,每个元素是 { id, text, completed } 对象。编写 addTodo 函数:创建新待办对象,push 到数组,触发渲染。

    代码
    let todos = [];
    let nextId = 1;
    
    function addTodo(text) {
      todos.push({ id: nextId++, text, completed: false });
      render();
    }

    预期结果

    调用 addTodo(“学习 JS”) 后数组新增一条待办。

  3. 3

    实现渲染函数

    编写 render 函数:清空列表容器,遍历数组为每条待办创建 li,包含文本、完成按钮和删除按钮。已完成的加划线样式。

    代码
    const listEl = document.querySelector('#todo-list');
    
    function render() {
      listEl.innerHTML = '';
      todos.forEach(todo => {
        const li = document.createElement('li');
        li.innerHTML = `
          <span class="${todo.completed ? 'done' : ''}">${todo.text}</span>
          <button data-action="toggle" data-id="${todo.id}">完成</button>
          <button data-action="delete" data-id="${todo.id}">删除</button>
        `;
        listEl.appendChild(li);
      });
    }

    预期结果

    调用 render 后列表显示所有待办项。

  4. 4

    用事件委托处理列表交互

    给列表容器绑定 click 事件(事件委托),根据 data-action 判断是完成还是删除,根据 data-id 找到对应待办并操作数组,再重新渲染。

    代码
    listEl.addEventListener('click', (e) => {
      const action = e.target.dataset.action;
      const id = parseInt(e.target.dataset.id);
      if (!action) return;
    
      if (action === 'toggle') {
        todos = todos.map(t =>
          t.id === id ? { ...t, completed: !t.completed } : t
        );
      } else if (action === 'delete') {
        todos = todos.filter(t => t.id !== id);
      }
      render();
    });

    预期结果

    点击“完成”切换划线状态,点击“删除”移除待办。

  5. 5

    绑定添加功能并测试

    给添加按钮绑定 click 事件:读取输入框值,非空时调用 addTodo 并清空输入框。回车也能添加。测试完整流程。

    代码
    const inputEl = document.querySelector('#todo-input');
    const addBtn = document.querySelector('#add-btn');
    
    function handleAdd() {
      const text = inputEl.value.trim();
      if (text) {
        addTodo(text);
        inputEl.value = '';
      }
    }
    
    addBtn.addEventListener('click', handleAdd);
    inputEl.addEventListener('keydown', (e) => {
      if (e.key === 'Enter') handleAdd();
    });

    预期结果

    输入文字点击添加或按回车,新待办出现在列表中。

自己动手试试

你学到了什么

你实现了一个完整的待办列表——这是前端最经典的练手项目。掌握了数据驱动渲染、事件委托、数组不可变更新(map/filter)等核心模式。这些模式在 React、Vue 等框架中同样适用。

相关资源

相关课程

  • 数组

    学习 map、filter 等数组方法。

  • DOM 操作

    动态创建和更新 DOM。

相关练习

相关工具

相关参考文档

相关错误

相关术语

相关术语

新手友好的术语表用大白话解释编程术语——变量、函数、DOM、Promise 等等。

相关错误

用大白话解释常见错误——什么意思、为什么发生、如何修复。

← 返回主题