coords属性只接受基于图片原始尺寸的整数像素值,无法直接使用百分比或css缩放;需通过监听load和resizeobserver动态按比例重算坐标,并注意poly闭合、空格清洗及移动端触控尺寸限制。

coords 坐标为什么不能直接写百分比或用 CSS 缩放
因为 coords 属性只接受纯整数像素值,且基准永远是图片的原始尺寸(img.naturalWidth/img.naturalHeight),不是渲染后的宽高。你写 img { width: 100%; height: auto; },图片被拉伸了,但 coords="100,200,300,400" 还是按原始图的 100px、200px 解析——热区就漂移了。CSS 的 transform: scale()、object-fit: cover、甚至 @2x 图片未除 DPR,都会让坐标和实际点击区域错开。
监听 load + resize 重算 coords 的最小可行代码
必须等图片加载完成才能读 naturalWidth,否则拿到 0;窗口缩放时也要重算,但别直接绑 window.onresize——移动端滚动、横竖屏切换会高频触发。推荐组合:
- 用
img.addEventListener('load', ...)初始化一次 - 用
ResizeObserver监听图片元素自身尺寸变化(比监听 window 更精准) - 每次重算前先对比
img.offsetWidth和上次缓存值,避免无意义更新 -
coords字符串要.split(',').map(Number)转数字,再按奇偶索引分别乘scaleX和scaleY,最后Math.round()取整
示例核心逻辑:
const img = document.querySelector('img[usemap]');
const map = document.querySelector(`map[name="${img.useMap.slice(1)}"]`);
const areas = map.querySelectorAll('area');
<p>const updateCoords = () => {
const scaleX = img.offsetWidth / img.naturalWidth;
const scaleY = img.offsetHeight / img.naturalHeight;</p><p>areas.forEach(area => {
const coords = area.coords.split(',').map(Number);
const scaled = coords.map((v, i) =>
i % 2 === 0 ? Math.round(v <em> scaleX) : Math.round(v </em> scaleY)
);
area.coords = scaled.join(',');
});
};</p><p>img.addEventListener('load', updateCoords);
new ResizeObserver(updateCoords).observe(img);</p>
poly 多边形热区闭合与空格陷阱
shape="poly" 不会自动闭合路径,coords="10,20,30,40,50,60" 是两条线段,不是三角形。必须手动重复首顶点:coords="10,20,30,40,50,60,10,20"(8 个整数)。常见失效原因:
- 设计工具导出坐标带空格:
"10, 20,30,40"→ 浏览器只取到"10",后面全丢 - 坐标含小数:
"100.5,200.3"→ 截断为"100,200",后续全失效 - 复制时混入换行或中文逗号,字符串解析直接中断
- 首尾坐标不一致,比如
"10,20,...,9,19"(差 1px)→ 某些浏览器渲染异常
修复建议:JS 中统一用 .replace(/\s+/g, '').replace(/,/g, ',') 清洗字符串,再 .split(',')。
响应式页面中真正该放弃
当你的页面有以下任一情况,硬搞 coords 自适应就是给自己挖坑:
- 图片用了
object-fit: cover或contain—— 等比缩放逻辑完全失效,得先算裁剪框再映射 - 需要适配高 DPR 屏幕(如 iPhone 的 2x/3x)且设计师给的是 @2x 标注 —— 你得在 JS 里动态除以
window.devicePixelRatio - 热区形状复杂(贝塞尔曲线、不规则镂空)、或需 hover 动效、或要支持键盘焦点 ——
<area>不支持伪类、无 focusable 属性 - 已有 SVG 工作流,或团队熟悉 D3 / Snap.svg —— 改用
<svg><polygon></polygon></svg>几乎零成本迁移
最易被忽略的一点:移动端触控最小推荐尺寸是 44×44px,而 coords 缩放后常低于此值,导致点不中——这不是 bug,是物理尺寸不足。此时哪怕 JS 算得再准,用户也点不准。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











