待办应用点击LI切换状态时如何避免重复添加SPAN元素?
问题根因
你的代码存在3个核心问题导致span重复生成、无法正常删除:
- 逻辑分支判断错误:
classList.toggle()返回false时代表已经成功移除red类,你后续写的else if (this.classList.contains("red"))条件永远不成立,删除span的代码完全不会执行 - API调用错误:原生JS不存在
getElementByTagName方法,正确写法为getElementsByTagName,且该方法返回的是元素集合,需要取下标[0]才能拿到对应的span元素 - 无重复校验:每次切换
red类生效时都直接新建span元素,没有先判断当前li下是否已经存在span,导致重复生成
修复方案
直接修改myList函数即可,其余代码无需改动,同时额外添加了点击span时的事件冒泡阻止,避免点击删除按钮时触发li的点击逻辑:
function myList() { const isRed = this.classList.toggle("red"); // 先查询当前li下是否已有span const existSpan = this.querySelector("span"); if (isRed) { // 不存在span才创建,避免重复生成 if (!existSpan) { const span = document.createElement("span"); span.innerHTML = "×"; span.addEventListener("click", function(e) { // 阻止事件冒泡,避免触发父元素li的点击事件 e.stopPropagation(); this.parentElement.remove(); }); this.appendChild(span); } } else { // 取消red类时,存在span就直接删除 if (existSpan) { existSpan.remove(); } } }
可选优化思路
如果不想频繁操作DOM创建/删除span,也可以直接把span默认写到所有li元素中,通过CSS控制显示隐藏,逻辑更简单:
/* 默认隐藏span */ li span { display: none; } /* li有red类时显示span */ li.red span { display: inline-block; }
这种方案下JS只需要处理类名切换即可,不需要操作span的创建删除。
内容的提问来源于stack exchange,提问作者TomDev
相关产品推荐
相关产品推荐

