实现Image Map中Area标签鼠标悬停变色的问题求助
实现图像映射区域悬停变色的方案
<area>标签本身是不可交互样式的特殊元素,直接通过CSS设置背景色、滤镜等属性不会生效——它只是定义了可点击的热点区域,并不在页面上渲染可见元素。下面提供两种可行的实现方式:
方法一:使用SVG叠加层(推荐)
把图像映射的坐标转换成对应的SVG路径,将SVG放在图片上方作为透明层,通过SVG路径的hover样式实现变色效果:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>地图悬停效果</title> <style> .map-container { position: relative; display: inline-block; } .map-svg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } .map-svg path { fill: transparent; cursor: pointer; transition: fill 0.3s; } .map-svg path:hover { fill: rgba(255, 0, 0, 0.5); /* 悬停时的半透明红色 */ } </style> </head> <body> <div class="map-container"> <img src="전국지도.png" alt="전국지도"> <svg class="map-svg" viewBox="0 0 [图片宽度] [图片高度]"> <!-- 对应原area的poly坐标,转换为SVG路径 --> <path d="M140 147 L139 153 L143 157 L148 163 L157 164 L165 164 L172 160 L174 152 L169 145 L165 135 L159 139 L153 141 L149 145 Z" title="서울 관광지" /> <path d="M121 146 L121 159 L122 170 L125 175 L133 170 L135 155 L131 149 Z" title="인천 관광지" /> <path d="M115 126 L128 127 L128 105 L140 98 L147 86 L156 81 L156 73 L174 71 L181 81 L186 77 L187 86 L198 87 L205 99 L217 110 L209 131 L237 154 L229 195 L214 212 L185 229 L170 223 L141 229 L139 210 L140 201 L125 194 L117 185 L140 182 L130 176 L120 165 L120 159 L123 149 L117 143 L115 137 Z" title="경기 관광지" /> </svg> </div> </body> </html>
注意事项:
- 替换
viewBox里的[图片宽度] [图片高度]为你的实际地图图片尺寸,确保SVG路径和图片完全对齐。 - SVG路径的
d属性是把原<area>的coords坐标转换成L(连线)指令,最后用Z闭合路径。
方法二:JavaScript动态生成可交互元素
通过JavaScript读取<area>的坐标,创建对应形状的元素,设置clip-path匹配热点区域,然后添加hover样式:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>地图悬停效果</title> <style> .map-container { position: relative; display: inline-block; } .map-area-overlay { position: absolute; top: 0; left: 0; cursor: pointer; background-color: rgba(255, 0, 0, 0.5); opacity: 0; transition: opacity 0.3s; } .map-area-overlay:hover { opacity: 1; } </style> </head> <body> <div class="map-container"> <img src="전국지도.png" usemap="#image-map" alt="전국지도"> <map name="image-map"> <area target="_blank" alt="서울 관광지" title="서울 관광지" href="" coords="140,147,139,153,143,157,148,163,157,164,165,164,172,160,174,152,169,145,165,135,159,139,153,141,149,145" shape="poly"> <area target="_blank" alt="인천 관광지" title="인천 관광지" href="" coords="121,146,121,159,122,170,125,175,133,170,135,155,131,149" shape="poly"> <area target="_blank" alt="경기 관광지" title="경기 관광지" href="" coords="115,126,128,127,128,105,140,98,147,86,156,81,156,73,174,71,181,81,186,77,187,86,198,87,205,99,217,110,209,131,237,154,229,195,214,212,185,229,170,223,141,229,139,210,140,201,125,194,117,185,140,182,130,176,120,165,120,159,123,149,117,143,115,137" shape="poly"> </map> </div> <script> const mapContainer = document.querySelector('.map-container'); const areas = document.querySelectorAll('area'); const img = mapContainer.querySelector('img'); // 等待图片加载完成再计算尺寸 img.onload = function() { const imgWidth = img.offsetWidth; const imgHeight = img.offsetHeight; areas.forEach(area => { const coords = area.coords.split(',').map(Number); const shape = area.shape; // 创建覆盖层元素 const overlay = document.createElement('div'); overlay.className = 'map-area-overlay'; overlay.title = area.title; // 根据形状设置clip-path if (shape === 'poly') { const pathCoords = coords.reduce((acc, val, idx) => { return acc + (idx % 2 === 0 ? `${val}px,` : `${val}px `); }, 'polygon(').trim() + ')'; overlay.style.clipPath = pathCoords; } // 覆盖层占满容器 overlay.style.width = `${imgWidth}px`; overlay.style.height = `${imgHeight}px`; mapContainer.appendChild(overlay); }); }; </script> </body> </html>
说明:
- 这种方法不需要手动转换坐标,直接复用原
<area>的coords和shape属性。 - 依赖图片加载完成后获取尺寸,确保覆盖层和地图对齐。
内容的提问来源于stack exchange,提问作者Soon_Coding
相关产品推荐
相关产品推荐

