如何用JavaScript为多个<li>元素点击时应用删除线样式?
点击所有元素(含动态新增)添加删除线的实现方案
问题现状
当前代码仅能让页面中第一个
document.querySelector("li")只会匹配页面中第一个符合条件的- ,无法选中所有现有
- 动态创建的
- 没有绑定点击事件,自然无法触发样式变更
原始代码
JavaScript代码
var button = document.getElementById("enter"); var input = document.getElementById("userinput"); var ul = document.querySelector("ul"); var li = document.querySelector("li"); function inputLength() { return input.value.length; } function createListElement() { var li = document.createElement("li"); li.appendChild(document.createTextNode(input.value)); ul.appendChild(li); input.value = ""; } function addListAfterClick() { if (inputLength() > 0) { createListElement(); } } function addListAfterKeydown(event) { if (inputLength() > 0 && event.key === "Enter") { createListElement(); } } button.addEventListener("click", addListAfterClick); input.addEventListener("keydown", addListAfterKeydown); li.addEventListener("click", function() { li.classList.add("done"); } )
CSS代码
.coolTitle { text-align: center; font-family: 'Oswald', Helvetica, sans-serif; font-size: 40px; transform: skewY(-10deg); letter-spacing: 4px; word-spacing: -8px; color: tomato; text-shadow: -1px -1px 0 firebrick, -2px -2px 0 firebrick, -3px -3px 0 firebrick, -4px -4px 0 firebrick, -5px -5px 0 firebrick, -6px -6px 0 firebrick, -7px -7px 0 firebrick, -8px -8px 0 firebrick, -30px 20px 40px dimgrey; } .done { text-decoration: line-through; }
修改方案(推荐使用事件委托)
事件委托利用事件冒泡机制,将点击事件绑定到静态存在的父元素<ul>上,这样不管是原有还是动态新增的<li>,点击时都会触发父元素的事件,再通过判断事件源来处理逻辑,这种方式更高效,无需给每个新元素单独绑定事件。
修改后的JavaScript代码
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); input.value = ""; } function addListAfterClick() { if (inputLength() > 0) { createListElement(); } } function addListAfterKeydown(event) { if (inputLength() > 0 && event.key === "Enter") { createListElement(); } } button.addEventListener("click", addListAfterClick); input.addEventListener("keydown", addListAfterKeydown); // 替换原有li的事件绑定,改用事件委托 ul.addEventListener("click", function(event) { // 判断点击的元素是否是li if (event.target.tagName === "LI") { // 使用toggle可以实现点击添加/移除删除线的切换效果,比add更灵活 event.target.classList.toggle("done"); } });
另一种方案:给动态创建的
如果不想用事件委托,也可以在创建<li>的时候直接给它绑定点击事件:
function createListElement() { var li = document.createElement("li"); li.appendChild(document.createTextNode(input.value)); // 给新创建的li绑定点击事件 li.addEventListener("click", function() { this.classList.toggle("done"); }); ul.appendChild(li); input.value = ""; } // 同时还要给页面原有所有li绑定事件 document.querySelectorAll("li").forEach(function(li) { li.addEventListener("click", function() { this.classList.toggle("done"); }); });
这种方式需要分别处理原有元素和新增元素,当页面原有li较多时,效率不如事件委托。
内容的提问来源于stack exchange,提问作者SSponge9
相关产品推荐
相关产品推荐

