You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用addEventListener避免代码重复,实现点击对应触发函数的方案

解决方案

一、统一事件监听的区分逻辑

你可以通过自定义属性给不同功能的元素标记身份,在统一的监听函数里判断后调用对应处理函数。先给你的复选框和删除按钮加上data-action属性:

<!-- 复选框 -->
<input type="checkbox" class="hidden-checkbox add-click-listener" data-action="toggle-status" id="checkbox-xxx">
<!-- 删除按钮 -->
<button class="trash-btn add-click-listener" data-action="delete" id="remove-xxx">删除</button>

然后优化事件监听代码:

document.querySelectorAll('.add-click-listener').forEach(item => {
  item.addEventListener('click', (event) => {
    const target = event.currentTarget as HTMLElement;
    const action = target.dataset.action;
    
    switch(action) {
      case 'delete':
        deleteTask(event);
        break;
      case 'toggle-status':
        checkboxStatusShift(event);
        break;
    }
  })
})

二、修复deleteTask函数的bug

你当前的代码会固定删除数组第一个元素,而不是对应ID的任务,同时优化TypeScript类型定义:

function deleteTask(event: MouseEvent) {
  const target = event.currentTarget as HTMLButtonElement;
  const buttonId = target.id?.replace('remove-', '');
  if (!buttonId) return; // 避免ID格式错误导致后续报错

  // 找到对应任务的索引
  const taskIndex = todoDatabase.findIndex(task => task.id === buttonId);
  if (taskIndex !== -1) {
    todoDatabase.splice(taskIndex, 1);
    printTodoList();
  }
}

三、实现复选框的checkboxStatusShift函数

需求是勾选后将任务移到列表末尾,核心逻辑是把对应任务从数组中移除,再追加到数组最后,然后重新渲染:

function checkboxStatusShift(event: MouseEvent) {
  const target = event.currentTarget as HTMLInputElement;
  const checkboxId = target.id?.replace('checkbox-', '');
  if (!checkboxId) return;

  const taskIndex = todoDatabase.findIndex(task => task.id === checkboxId);
  if (taskIndex !== -1) {
    // 移除目标任务并保存
    const [movedTask] = todoDatabase.splice(taskIndex, 1);
    // 追加到数组末尾
    todoDatabase.push(movedTask);
    // 重新渲染列表
    printTodoList();
    // 渲染后恢复复选框勾选状态(因为重新渲染会重置DOM)
    setTimeout(() => {
      const newCheckbox = document.getElementById(`checkbox-${checkboxId}`) as HTMLInputElement;
      if (newCheckbox) newCheckbox.checked = true;
    }, 0);
  }
}

额外优化建议

如果后续会动态新增任务,逐个绑定事件会失效,推荐用事件委托代替:给任务列表的父容器绑定一次事件,通过事件冒泡处理所有子元素的点击:

// 假设任务列表的父容器ID是todo-list
document.getElementById('todo-list')?.addEventListener('click', (event) => {
  const target = event.target as HTMLElement;
  // 找到点击元素所属的功能按钮/复选框
  const actionElement = target.closest('.add-click-listener');
  if (!actionElement) return;

  const action = actionElement.dataset.action;
  switch(action) {
    case 'delete':
      deleteTask(event);
      break;
    case 'toggle-status':
      checkboxStatusShift(event);
      break;
  }
});

内容的提问来源于stack exchange,提问作者Joel del Pilar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 17:30:46