JavaScript购物列表:新增元素后删除与切换按钮失效求助
嗨,我来帮你搞定这个购物列表的问题~你遇到的删除和切换失效的核心原因是动态创建的元素没有绑定事件监听,下面一步步给你拆解:
为什么新增的元素没反应?
你在页面加载完成后,通过document.querySelectorAll("li")和document.getElementsByClassName("Delete")获取了当时存在的元素,然后给它们绑定了点击事件。但当你用createListElement新增li和按钮时,这些新元素并没有被包含在之前的集合里,自然也就没有事件监听,所以点击没效果。
另外你的代码里还重复写了两遍给li绑定toggle事件的代码和liClick函数,这是冗余的,先把重复的部分删掉哦。
解决方案1:创建元素时直接绑定事件
最简单的方式就是在createListElement函数里,创建完新的li和Delete按钮后,立刻给它们绑定对应的事件:
修改后的createListElement函数:
function createListElement() { var li = document.createElement("li"); li.appendChild(document.createTextNode(input.value)); // 给新li绑定toggle事件 li.addEventListener("click", liClick); ul.appendChild(li); var button = document.createElement("button"); button.appendChild(document.createTextNode("Delete!")); button.classList.add("Delete"); // 给新按钮绑定删除事件 button.addEventListener("click", deleteItem); li.appendChild(button); // 清空输入框(你原来的input.value=""写错位置了,应该放在这里) input.value = ""; }
同时记得把你原来代码里重复的事件绑定代码删掉,只保留一遍初始化的绑定即可。
解决方案2:事件委托(更推荐)
如果以后还要频繁动态添加元素,用事件委托会更高效——把事件绑定在父元素(这里是ul)上,利用事件冒泡机制,不管是原来的还是新增的子元素,触发事件时都会冒泡到父元素,我们只需要判断点击的目标是什么,再执行对应操作:
这种方式你甚至可以删掉原来的两个循环绑定事件的代码,只需要给ul加一个监听:
// 替换原来的三个事件绑定循环 ul.addEventListener("click", function(event) { // 判断点击的是li元素 if (event.target.tagName === "LI") { event.target.classList.toggle("done"); } // 判断点击的是Delete按钮 if (event.target.classList.contains("Delete")) { event.target.parentElement.remove(); } });
这样不管是页面初始的元素,还是后来新增的,点击后都会正常触发切换或删除操作,而且代码更简洁。
最后调整你的完整代码
这里给你整合了事件委托方案的完整代码,去掉了冗余部分:
var button = document.getElementById("enter"); var input = document.getElementById("userinput"); var ul = document.querySelector("ul"); function inputLength() { return input.value.length; } function createListElement() { var li = document.createElement("li"); li.appendChild(document.createTextNode(input.value)); ul.appendChild(li); var button = document.createElement("button"); button.appendChild(document.createTextNode("Delete!")); button.classList.add("Delete"); li.appendChild(button); input.value = ""; // 移到这里,添加完元素后清空输入框 } function addListAfterClick() { if (inputLength() > 0) { createListElement(); } } function addListAfterKeypress(event) { if (inputLength() > 0 && event.keyCode === 13) { createListElement(); } } button.addEventListener("click", addListAfterClick); input.addEventListener("keypress", addListAfterKeypress); // 用事件委托处理所有li的toggle和按钮的删除 ul.addEventListener("click", function(event) { if (event.target.tagName === "LI") { event.target.classList.toggle("done"); } if (event.target.classList.contains("Delete")) { event.target.parentElement.remove(); } });
这样修改后,新增的元素就能正常触发删除和切换操作啦~
内容的提问来源于stack exchange,提问作者user13713231

