多ID场景下如何用纯JavaScript重写jQuery鼠标交互代码?
批量处理鼠标交互的纯JavaScript优化方案
原始需求
原本用jQuery实现了鼠标进入/离开#perso1、#perso2元素时,控制对应类名的元素显示隐藏。现在要转成纯JavaScript版本,且需批量处理6个同类型的perso元素,避免重复编写相同逻辑。
用户原始jQuery代码
$('#perso1').mouseenter(function() { $('.perso1').show(); $('.name1').show(); $('.perso2').hide(); $('.name2').hide(); }); $('#perso1').mouseleave(function() { $('.perso2').hide(); $('.name1').hide(); $('.perso1').show(); $('.name1').show(); }); $('#perso2').mouseenter(function() { $('.perso2').show(); $('.name2').show(); $('.perso1').hide(); $('.name1').hide(); }); $('#perso2').mouseleave(function() { $('.perso2').hide(); $('.name2').hide(); $('.perso1').show(); $('.name1').show(); });
用户自行编写的纯JS代码(存在问题)
document.getElementById("perso2,").onmouseenter = function() {mouseEnter()}; document.getElementById("perso2").onmouseleave = function() {mouseLeave()}; function mouseEnter() { document.getElementByClassName("perso1").style.display = 'none'; document.getElementByClassName("name1").style.display = 'none'; document.getElementByClassName("perso2-2").style.display = 'block'; document.getElementByClassName("name2").style.display = 'block'; } function mouseLeave() { document.getElementByClassName("perso1").style.display = 'block'; document.getElementByClassName("perso2").style.display = 'none'; document.getElementByClassName("name1").style.display = 'block'; document.getElementByClassName("name2").style.display = 'none'; }
代码问题分析
- 拼写错误:
getElementByClassName应为getElementsByClassName(复数形式,返回元素集合而非单个元素) - 无效选择器:
document.getElementById("perso2,")多了逗号,无法找到目标元素 - 硬编码逻辑:仅针对单个元素编写,无法扩展到6个
perso元素,代码冗余
优化后的纯JS代码
// 批量处理1-6号perso元素 for (let i = 1; i <= 6; i++) { const triggerElement = document.getElementById(`perso${i}`); if (!triggerElement) continue; // 元素不存在时跳过,避免报错 // 鼠标进入事件:隐藏所有元素,显示当前对应元素 triggerElement.addEventListener('mouseenter', () => { hideAllPersoElements(); showTargetElements(i); }); // 鼠标离开事件:隐藏所有元素,恢复显示默认的perso1和name1 triggerElement.addEventListener('mouseleave', () => { hideAllPersoElements(); showTargetElements(1); }); } // 隐藏所有perso和name类元素 function hideAllPersoElements() { for (let i = 1; i <= 6; i++) { // 将HTMLCollection转换为数组后遍历操作 Array.from(document.getElementsByClassName(`perso${i}`)).forEach(el => { el.style.display = 'none'; }); Array.from(document.getElementsByClassName(`name${i}`)).forEach(el => { el.style.display = 'none'; }); } } // 显示指定编号的perso和name元素 function showTargetElements(num) { Array.from(document.getElementsByClassName(`perso${num}`)).forEach(el => { el.style.display = 'block'; }); Array.from(document.getElementsByClassName(`name${num}`)).forEach(el => { el.style.display = 'block'; }); }
优化思路说明
- 批量绑定事件:通过循环遍历1-6的编号,一次性完成所有
perso元素的事件绑定,避免重复代码 - 通用函数封装:将隐藏所有元素、显示指定元素的逻辑封装为独立函数,提高代码复用性
- 兼容元素集合:
getElementsByClassName返回HTMLCollection,需用Array.from转换为数组后遍历操作 - 错误防护:增加元素存在性检查,防止因元素未找到导致的脚本报错
- 灵活扩展:若后续需要增加更多
perso元素,只需修改循环的结束值即可
内容的提问来源于stack exchange,提问作者Aladin Akkari
相关产品推荐
相关产品推荐

