如何在 vanilla-typescript todo 应用程序中设置删除项目按钮

How to set up remove item buttons in vanilla-typescript todo app

我正在使用 vanilla typescript 创建一个基本的待办事项列表应用程序。将按钮附加到每个列表项后,我希望在用户单击特定列表项上的按钮时删除这些项目。为执行此操作,我尝试在 index.ts 中添加第二个 addEventListener 方法来监听移除按钮点击,然后移除父元素的子元素。我的 addEventListener 方法如下所示:

listItemBtn.addEventListener("click", (e: Event) => {
  const element = e.target as HTMLUListElement;
  element.removeChild(element);
});

但是,我不断在控制台中收到一条错误消息,提示“未捕获的类型错误:无法读取 属性 'addEventListener' of null”。我不确定为什么我不能将 .addEventListener 附加到 listItemBtn 而没有错误。知道如何解决这个问题吗?

这是一个link到CodeSandBox中的项目:https://codesandbox.io/s/vanilla-typescript-forked-xnnf4

您正在寻找 listItemBtn 之前的内容。如果你添加这一行

document.querySelectorAll("#listItemBtn").forEach(console.log);

form.addEventListener 的末尾,您将开始看到它填充了元素。


此代码中有很多地方需要更改。使用 as 时要小心,因为它可以防止 Typescript 看到潜在的运行时错误,比如元素可能是 null.

您的问题是如何设置删除按钮,所以我实际上认为 querySelectorAll 不是正确的方法。我会在您创建 btn 的位置添加侦听器 。那时您已经将 button 元素作为变量。

你的监听函数本身有问题。同样,您在 const element = e.target as HTMLUListElement; 中遇到了麻烦的 as,因为目标是 button,而不是 li

element.removeChild(element) 是错误的,因为您需要在父对象上调用 removeChild,例如 parent.removeChild(child)。您可以看起来像 element.parentElement(可能是 null)。由于我们将此函数移动到 ListTemplate 中,因此我们可以访问父 li 变量。我们要删除的元素是 ul 中的 li。所以实际上我们的 e.targetbtn 并不是很有用。

ListTemplaterender 方法中,执行以下操作:

btn.addEventListener("click", () => {
   this.container.removeChild(li);
});

如评论中所述,您不应设置不唯一的 id。您可以使用 className 代替:

btn.className = "listItemBtn";

但您只需要它来设计样式。我们不再在任何地方查询此元素。


您可以清理 form 提交侦听器。没有理由创建一个变量然后分配它。直接赋值就行了。这也消除了手动指定类型的需要,因为根据您设置给变量的值可以知道类型。

form.addEventListener("submit", (e) => {
  e.preventDefault();

  const value = listItem.value;

  const doc = new ListItem(value);

  list.render(doc, value, "start");
});