如何通过按钮Hover为对应元素批量添加/移除类(匹配成对元素)
问题
我需要实现鼠标悬停对应按钮时,给英国地图的指定SVG区域添加/移除样式。目前已经获取了所有按钮和区域元素,但不想为每个按钮重复编写事件绑定代码(后续还要添加更多地区元素),希望用少量函数完成功能。
现有获取元素的代码:
// England Buttons const grBtn = document.querySelector(".eng-gr"); const seBtn = document.querySelector(".eng-se"); const eeBtn = document.querySelector(".eng-ee"); const emBtn = document.querySelector(".eng-em"); const yhBtn = document.querySelector(".eng-yh"); const neBtn = document.querySelector(".eng-ne"); const nwBtn = document.querySelector(".eng-nw"); const wmBtn = document.querySelector(".eng-wm"); const swBtn = document.querySelector(".eng-sw"); // England Region const grRgn = document.querySelector(".greater-london"); const seRgn = document.querySelector(".south-east-england"); const eeRgn = document.querySelector(".east-england"); const emRgn = document.querySelector(".east-midlands"); const yhRgn = document.querySelector(".yorkshire-humber"); const neRgn = document.querySelector(".north-east-england"); const nwRgn = document.querySelector(".north-west-england"); const wmRgn = document.querySelector(".west-midlands"); const swRgn = document.querySelector(".south-west-england");
当前手动绑定事件的示例:
grBtn.addEventListener("mouseover", function () { grRgn.classList.add("rgn-hover"); }); grBtn.addEventListener("mouseout", function () { grRgn.classList.remove("rgn-hover"); });
优化方案
方法1:通过数据属性建立按钮与区域的关联
给每个按钮添加data-region属性,值对应目标SVG区域的类名,这样可以用统一的逻辑处理所有按钮的事件:
- 先修改HTML中的按钮元素,添加数据属性:
<button class="eng-gr" data-region="greater-london">大伦敦</button> <button class="eng-se" data-region="south-east-england">英格兰东南部</button> <!-- 其余按钮按对应区域类名添加data-region属性 -->
- 编写统一的事件处理函数并批量绑定:
// 获取所有带data-region属性的按钮 const regionButtons = document.querySelectorAll('[data-region]'); // 统一处理鼠标悬停/离开事件 function handleRegionHover(e) { const targetRegionClass = e.target.dataset.region; const regionElement = document.querySelector(`.${targetRegionClass}`); // 防止找不到对应区域的情况 if (!regionElement) return; if (e.type === 'mouseover') { regionElement.classList.add('rgn-hover'); } else { regionElement.classList.remove('rgn-hover'); } } // 给所有按钮绑定事件 regionButtons.forEach(button => { button.addEventListener('mouseover', handleRegionHover); button.addEventListener('mouseout', handleRegionHover); });
方法2:用映射对象关联按钮与区域(无需修改HTML)
如果不想改动现有HTML结构,可以提前定义一个映射对象,把按钮选择器和对应区域的选择器一一对应,再批量绑定事件:
// 定义按钮选择器与区域选择器的映射关系 const regionMapping = { ".eng-gr": ".greater-london", ".eng-se": ".south-east-england", ".eng-ee": ".east-england", ".eng-em": ".east-midlands", ".eng-yh": ".yorkshire-humber", ".eng-ne": ".north-east-england", ".eng-nw": ".north-west-england", ".eng-wm": ".west-midlands", ".eng-sw": ".south-west-england" }; // 遍历映射对象,批量绑定事件 Object.entries(regionMapping).forEach(([btnSelector, regionSelector]) => { const button = document.querySelector(btnSelector); const region = document.querySelector(regionSelector); // 跳过获取失败的元素 if (!button || !region) return; button.addEventListener('mouseover', () => region.classList.add('rgn-hover')); button.addEventListener('mouseout', () => region.classList.remove('rgn-hover')); });
两种方案的优势
- 都避免了重复编写事件绑定代码,后续新增地区时,只需要补充
data-region属性(方法1)或者在映射对象里添加一组键值对(方法2)即可,无需修改核心逻辑。 - 方法1更符合HTML语义化,结构清晰,适合后续大量新增元素的场景;方法2无需改动现有HTML,适合已有结构不便调整的情况。
内容的提问来源于stack exchange,提问作者MartynMc
相关产品推荐
相关产品推荐

