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

点击li元素切换done类实现文本删除线功能报错求助

解决点击LI元素切换删除线样式的问题

嘿,我来帮你搞定这个问题!你遇到的错误主要是因为对DOM元素集合的处理方式不对,下面我一步步给你解释并给出解决方案:

问题根源分析

  1. getElementsByTagName("li"):这个方法返回的是一个HTMLCollection(类数组对象),它本身并没有addEventListener方法,所以你直接给整个集合绑定事件肯定会失败。
  2. querySelector("li"):只会匹配页面中第一个<li>元素,所以只有第一个列表项能触发效果,其他的都不行。
  3. querySelectorAll("li"):返回的是NodeList,你之前的错误是直接在整个NodeList上调用classList.toggle——但这个方法是属于单个DOM元素的,不是集合,所以会报"Cannot read property 'toggle' of undefined"的错误。

正确解决方案

下面给你三种可行的方法,你可以根据需求选择:

方法1:遍历所有LI元素绑定事件(现代浏览器适用)

用querySelectorAll获取所有li,然后通过forEach遍历每个元素,单独绑定点击事件:

// 获取页面中所有的li元素
const listItems = document.querySelectorAll("li");

// 给每个li添加点击事件
listItems.forEach(item => {
  item.addEventListener("click", function() {
    // 切换当前点击元素的done类
    this.classList.toggle("done");
  });
});

方法2:兼容旧浏览器的循环绑定

如果需要兼容不支持forEach的旧浏览器,可以用传统的for循环:

const listItems = document.getElementsByTagName("li");

// 遍历HTMLCollection中的每个元素
for (let i = 0; i < listItems.length; i++) {
  listItems[i].addEventListener("click", function() {
    this.classList.toggle("done");
  });
}

方法3:事件委托(推荐,支持动态添加的LI)

如果之后你会通过输入框动态添加新的列表项,上面两种方法不会给新元素绑定事件。这时候用事件委托更高效——把事件绑定在父元素<ul>上,利用事件冒泡来处理:

// 获取父元素ul
const shoppingList = document.querySelector("ul");

// 给ul绑定点击事件
shoppingList.addEventListener("click", function(e) {
  // 确保点击的是li元素
  if (e.target.tagName === "LI") {
    // 切换点击元素的done类
    e.target.classList.toggle("done");
  }
});

验证你的CSS

你的CSS代码是完全正确的:

.done { text-decoration: line-through; }

只要成功给li添加/移除done类,就会显示/隐藏删除线效果。

内容的提问来源于stack exchange,提问作者skylar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:16:00