JS代码重构:如何用单个事件处理器实现点击li切换背景与文本?
现有代码问题梳理
- 选择器语法错误:
querySelector匹配类名需要加前缀.,比如查找class为color1的元素要写document.querySelector('.color1'),你原代码漏掉了.导致无法获取到对应元素 innerHTML用法错误:innerHTML是DOM元素的属性,赋值写法为p1.innerHTML = '新内容',原写法document.innerHTML(p1)不符合语法规范- a标签默认行为未阻止:空href的a标签点击后会触发页面刷新,导致JS逻辑执行后马上被刷新覆盖,看不到效果
- 代码冗余:四个li的点击逻辑几乎完全一致,重复写四遍监听器不利于后续维护和扩展
优化实现方案
无需改动原有HTML的JS实现(事件委托方案,扩展性最高)
只给父元素ul绑定一个监听器就能处理所有子元素的点击,后续新增颜色选项不需要修改JS逻辑:
// 获取需要操作的公共元素 const nav = document.querySelector('.nav'); const textPara = document.querySelector('.para'); // 给导航父元素绑定点击事件 nav.addEventListener('click', function(e) { // 阻止a标签默认跳转刷新行为 e.preventDefault(); // 匹配当前点击位置最近的li父元素 const targetLi = e.target.closest('li'); // 如果点击的是ul空白区域,不执行后续逻辑 if(!targetLi) return; // 获取li的类名作为颜色标识 const colorVal = targetLi.className; // 修改页面背景色 document.body.style.backgroundColor = colorVal; // 修改p标签对应文本 textPara.innerHTML = `This is ${colorVal}`; })
兼容你原有写法的简化方案
如果习惯给每个li单独绑定监听器,可以用循环简化重复代码:
const colorList = ['color1', 'color2', 'color3', 'color4']; const textPara = document.querySelector('.para'); // 循环遍历所有颜色项绑定事件 colorList.forEach(color => { const navItem = document.querySelector(`.${color}`); navItem.addEventListener('click', e => { e.preventDefault(); document.body.style.backgroundColor = color; textPara.innerHTML = `This is ${color}`; }) })
补充说明
你可以把color1、color2替换为实际的颜色值(比如red、#ff0000、rgb(255,0,0)都可以),只要和li的类名对应即可;如果需要更灵活的配置,也可以给li加data-color、data-text自定义属性存储对应配置,逻辑适配性会更高。
内容的提问来源于stack exchange,提问作者yanus
相关产品推荐
相关产品推荐

