You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过按钮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区域的类名,这样可以用统一的逻辑处理所有按钮的事件:

  1. 先修改HTML中的按钮元素,添加数据属性:
<button class="eng-gr" data-region="greater-london">大伦敦</button>
<button class="eng-se" data-region="south-east-england">英格兰东南部</button>
<!-- 其余按钮按对应区域类名添加data-region属性 -->
  1. 编写统一的事件处理函数并批量绑定:
// 获取所有带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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 09:10:35