🐸 青蛙编程网
首页 / 前端 / jQuery / 8. 综合练习:待办清单

8. 综合练习:待办清单

这是什么:待办清单(ToDo List) = 一个最常见的小练手项目:输入任务、勾选完成、点叉删除,交互刚好覆盖整本教程。

为什么用:前面几章的工具都还停在「会写单条代码」,没人告诉你它们合起来能做成什么东西。做这个清单,你能把选择器、事件、DOM、动画一次性串起来用。

如何用:本章先写好 HTML 结构,再把添加任务、切换完成、删除、空状态提示这些功能逐个用 jQuery 实现出来。

8.1 效果预览

功能需求:

  1. 在输入框输入内容,按 Enter 键或点击「添加」按钮,可以新增一条待办事项
  2. 点击待办事项本身,切换「未完成/已完成」状态(已完成添加删除线样式)
  3. 点击每一项右侧的 ×,删除该项
  4. 新增的事项要有淡入动画效果,提升体验

8.2 HTML 结构

先搭建页面结构:

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <title>jQuery 待办清单</title>
    <style>
      body {
        font-family: 'Microsoft YaHei', sans-serif;
        background: #f5f5f5;
        padding: 40px 0;
      }
      .container {
        width: 400px;
        margin: 0 auto;
        background: #fff;
        padding: 30px;
        border-radius: 8px;
        box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
      }
      h2 {
        text-align: center;
        color: #333;
        margin-top: 0;
      }
      .input-box {
        display: flex;
        margin-bottom: 20px;
      }
      #taskInput {
        flex: 1;
        padding: 10px;
        border: 1px solid #ddd;
        border-radius: 4px 0 0 4px;
        outline: none;
        font-size: 14px;
      }
      #taskInput:focus {
        border-color: #4caf50;
      }
      #addBtn {
        padding: 10px 20px;
        background: #4caf50;
        color: #fff;
        border: none;
        border-radius: 0 4px 4px 0;
        cursor: pointer;
      }
      #addBtn:hover {
        background: #45a049;
      }
      #taskList {
        list-style: none;
        padding: 0;
        margin: 0;
      }
      #taskList li {
        padding: 12px 40px 12px 15px;
        background: #f9f9f9;
        margin-bottom: 8px;
        border-radius: 4px;
        position: relative;
        cursor: pointer;
        transition: all 0.2s;
        display: none; /* 初始隐藏,用于淡入动画 */
      }
      #taskList li:hover {
        background: #f1f1f1;
      }
      #taskList li.completed {
        text-decoration: line-through;
        color: #999;
        background: #e8f5e9;
      }
      .delete {
        position: absolute;
        right: 10px;
        top: 50%;
        transform: translateY(-50%);
        color: #f44336;
        font-size: 18px;
        cursor: pointer;
        width: 24px;
        height: 24px;
        line-height: 24px;
        text-align: center;
        border-radius: 50%;
        transition: all 0.2s;
      }
      .delete:hover {
        background: #ffebee;
      }
      .empty-tip {
        text-align: center;
        color: #999;
        font-size: 14px;
        padding: 20px 0;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <h2>jQuery 待办清单</h2>
      <div class="input-box">
        <input type="text" id="taskInput" placeholder="请输入待办事项..." />
        <button id="addBtn">添加</button>
      </div>
      <ul id="taskList"></ul>
      <p class="empty-tip" id="emptyTip">还没有待办事项,快添加一条吧~</p>
    </div>

    <!-- 引入 jQuery -->
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <script>
      // 待补充 jQuery 代码
    </script>
  </body>
</html>

8.3 jQuery 功能实现

我们需要用到:事件处理(click、keyup)、DOM 操作(append、remove)、选择器、类操作(toggleClass)、效果(fadeIn)。

$(function () {
  const $taskInput = $('#taskInput');
  const $taskList = $('#taskList');
  const $emptyTip = $('#emptyTip');

  // 更新空状态提示
  function updateEmptyTip() {
    if ($taskList.children().length === 0) {
      $emptyTip.show();
    } else {
      $emptyTip.hide();
    }
  }

  // 添加任务
  function addTask() {
    const taskText = $taskInput.val().trim();
    if (taskText === '') {
      alert('请输入任务内容!');
      $taskInput.focus();
      return;
    }

    // 创建新任务项
    const $li = $('<li></li>')
      .text(taskText)
      .append('<span class="delete">&times;</span>');

    // 添加到列表(淡入显示)
    $taskList.append($li);
    $li.fadeIn(300);

    // 清空输入框
    $taskInput.val('');
    $taskInput.focus();

    // 更新空提示
    updateEmptyTip();
  }

  // 点击添加按钮
  $('#addBtn').click(function () {
    addTask();
  });

  // 按回车键添加任务
  $taskInput.keyup(function (e) {
    if (e.key === 'Enter') {
      addTask();
    }
  });

  // 事件委托:切换完成状态(点击 li)
  $taskList.on('click', 'li', function () {
    $(this).toggleClass('completed');
  });

  // 事件委托:删除任务(点击 .delete)
  $taskList.on('click', '.delete', function (e) {
    e.stopPropagation(); // 阻止冒泡,避免触发 li 的点击事件
    const $li = $(this).parent();
    $li.fadeOut(300, function () {
      $(this).remove();
      updateEmptyTip();
    });
  });

  // 初始化空提示
  updateEmptyTip();
});

8.4 代码解析

  1. 防止空提交:输入内容去除空格后判断是否为空,避免添加空任务。
  2. 回车添加:监听 keyup 事件,按 Enter(e.key === 'Enter')时调用 addTask()。
  3. 事件委托:任务是动态添加的,用 on('click', 'li', ...) 和 on('click', '.delete', ...) 保证后添加的元素也能响应事件。
  4. 阻止冒泡:点击删除按钮 × 时,调用 e.stopPropagation(),避免同时触发父元素 li 的「切换完成状态」事件。
  5. 淡入淡出效果:新增用 .fadeIn(300),删除用 .fadeOut(300, function(){ $(this).remove() }),先淡出再从 DOM 中移除,效果更自然。
  6. 空状态提示:实时检测列表是否为空,显示/隐藏提示文字。

8.5 拓展练习(选做)

如果学有余力,可以尝试给这个待办清单增加以下功能:

  • 本地存储(localStorage):刷新页面后保留任务列表
  • 统计未完成数量:显示「剩余 X 项未完成」
  • 批量操作:一键清除所有已完成任务
  • 双击编辑:双击任务项可以直接编辑内容
  • 任务筛选:按「全部」「未完成」「已完成」筛选任务

这些拓展都可以用 jQuery + 原生 JS(localStorage)来实现,能进一步提升你的实战能力。

8.6 小结

恭喜你!完成了 jQuery 教程的全部章节。

通过这个待办清单练习,你综合运用了:

  • 选择器:选取输入框、列表、按钮等元素
  • 事件处理:点击、回车键、事件委托
  • DOM 操作:创建元素($('<li>'))、追加(append)、删除(remove)
  • 类操作:toggleClass 切换完成状态
  • 动画效果:fadeIn、fadeOut 增强用户体验

jQuery 教程到此结束。下一站去 JSON 教程学前后端传数据的通用格式,再用 AJAX 教程把数据真正请求回来、打通前后端;之后就可以继续学习更现代的前端技术(Vue、React 等)。

加油,继续前进! 🐸

📥 下载本章代码

ZIP 内含本章全部代码文件与说明,解压即用,与教程内容同步生成。