原生area标签coords不会随图片缩放自动更新,必须用JS手动重算并显式赋值;usemap与map的name必须逐字节完全匹配(含#、大小写、连字符);coords须基于naturalWidth/naturalHeight计算缩放比,且更新后必须调用setAttribute或直接赋值coords属性。

原生 <area> 标签的 coords 属性不会随图片缩放自动更新,必须用 JS 手动重算并显式赋值,否则热区在响应式页面中必然错位。
usemap 和 map name 必须逐字节匹配
这是热区“完全不响应”的最常见原因。浏览器对匹配极其严格,任何偏差都会导致整个 <map> 被忽略。
-
usemap值必须以#开头,比如usemap="#floor-plan" -
<map name="floor-plan">中的name必须和#后面的部分**完全一致**:大小写、连字符、空格都不能差 - 调试时别肉眼比对,直接复制
usemap的值,粘贴到<map>的name属性里再检查
coords 坐标必须基于 naturalWidth/naturalHeight 计算缩放比
浏览器永远用图片原始尺寸(img.naturalWidth / img.naturalHeight)作为 coords 的基准,CSS 缩放、max-width 或视口变化都不会改变这个基准。
- 先读取
img.naturalWidth和当前img.offsetWidth,算出横向缩放比:scaleX = img.offsetWidth / img.naturalWidth - 同理得
scaleY = img.offsetHeight / img.naturalHeight(非等比缩放时不能共用一个比例) - 对每个
<area>的coords字符串,按shape类型拆解: -rect→ 拆成 4 个数,分别乘scaleX, scaleY, scaleX, scaleY-circle→ 前两个乘对应比例,半径只乘scaleX(或取Math.min(scaleX, scaleY)防变形) -poly→ 每对坐标(x,y)分别乘scaleX和scaleY - 更新后必须调用
areaEl.setAttribute('coords', newCoordsStr),仅改 JS 变量无效
动态更新时机容易漏掉 img.load
图片还没加载完成时,naturalWidth 是 0,此时算缩放比会得 Infinity 或 NaN,后续所有坐标都错。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
立即学习“前端免费学习笔记(深入)”;
- 必须监听
img.addEventListener('load', updateCoords),不能只靠window.resize - 如果图片是通过 JS 动态插入或 src 后续才设置的,还要加
img.complete && img.naturalWidth判断 - 多个
<area>批量更新后,建议加setTimeout(() => {}, 0)让浏览器有间隙重绘热区高亮,尤其在 Safari 中能避免静默失效 - 别用
innerHTML替换整个<map>—— 旧热区注册不会清除,新<area>可能被跳过
poly 坐标字符串解析和拼接最容易出错
coords 是纯字符串,不是数组。手动 split(',') 再 map(Number) 后,必须确保输出仍是整数、逗号分隔、无空格,且总数为偶数。
- 错误示例:
"100, 200, 300, 400"(含空格)→ Safari 直接跳过该<area> - 正确做法:用
coords.trim().split(/\s*,\s*/).map(Number)清洗后再处理 -
poly首尾点不必强制闭合,但若设计稿导出时没重复首点,而你又依赖视觉闭合,就手动补上最后一组x1,y1 - 更新后拼接用
newCoords.join(','),别用toString()—— 它会在 IE 中多加逗号
真正麻烦的不是计算本身,而是每次图片尺寸变化都要重新触发整套流程:naturalWidth 是否就绪、offsetWidth 是否包含 border/padding、scaleY 在不同设备上是否稳定——这些细节稍有疏忽,热区就偏移几像素,用户点不中还查不出错。所以只要项目支持 SVG,优先用 <svg> + <path>,它天然适配缩放,不用操心像素映射。


















