如何遍历getElementsByTagName选中的li元素并为每个元素应用样式?
问题原因
- 第一行获取li元素时末尾添加了
[0],导致listItems变量实际指向页面首个li元素,而非li元素集合,没有length属性,循环逻辑无法执行 - HTMLCollection类型的DOM集合不能直接绑定事件,原代码如果去掉
[0]直接给listItems绑点击事件会直接报错
修正方案
根据不同需求有两种常见调整方式:
方式1:点击首个li时给所有li加删除线样式
保留原触发逻辑的修正代码:
// 单独获取首个li用于绑定点击事件 const firstLi = document.getElementsByTagName('li')[0]; // 获取所有li的集合用于批量修改样式 let listItems = document.getElementsByTagName('li'); const addItemInput = document.querySelector('input.addItemInput'); const addItemButton = document.querySelector('button.addItemButton'); const removeItemButton = document.querySelector('button.removeItemButton'); firstLi.addEventListener('click', () => { // 转成数组避免动态DOM集合的潜在问题 Array.from(listItems).forEach(item => { item.style.textDecoration = "line-through"; item.style.color = "gray"; }); }); addItemButton.addEventListener('click', () => { let todoList = document.getElementsByTagName('ul')[0]; let li = document.createElement('li'); li.textContent = addItemInput.value; // 替换innerHTML避免XSS风险 todoList.appendChild(li); addItemInput.value = ""; }); removeItemButton.addEventListener('click', () => { let todoList = document.getElementsByTagName('ul')[0]; let li = document.querySelector('li:first-child'); li && todoList.removeChild(li); // 加判断避免li不存在时报错 });
方式2:点击任意li时给当前点击的li加删除线样式
采用事件委托实现,动态新增的li也能自动生效:
const todoList = document.getElementsByTagName('ul')[0]; const addItemInput = document.querySelector('input.addItemInput'); const addItemButton = document.querySelector('button.addItemButton'); const removeItemButton = document.querySelector('button.removeItemButton'); // 事件委托绑定到父级ul,不需要给每个li单独绑事件 todoList.addEventListener('click', (e) => { if(e.target.tagName === 'LI') { e.target.style.textDecoration = "line-through"; e.target.style.color = "gray"; } }); addItemButton.addEventListener('click', () => { let li = document.createElement('li'); li.textContent = addItemInput.value; todoList.appendChild(li); addItemInput.value = ""; }); removeItemButton.addEventListener('click', () => { let li = document.querySelector('li:first-child'); li && todoList.removeChild(li); });
内容的提问来源于stack exchange,提问作者Enoch Okyere
相关产品推荐
相关产品推荐

