coords在响应式下必然错位,因其基于图片原始像素尺寸(naturalwidth/height),而css渲染宽高变化后缩放比需动态计算:横向用offsetwidth/naturalwidth、纵向用offsetheight/naturalheight,且rect/circle/poly需分别按对应方向缩放坐标,同时监听load和resize事件并校验naturalwidth>0,最后保留1位小数拼回coords字符串。

coords 为什么在响应式下必然错位
因为 coords 是纯像素值,绑定的是图片原始尺寸(naturalWidth/naturalHeight),不是 CSS 渲染后的宽高。只要图片用了 max-width: 100%、width: 50% 或任何非固定 width/height 属性,浏览器就无法自动缩放热区——这不是 bug,是规范如此。
常见错误现象:桌面调好坐标,移动端点击区域偏移、点不中、甚至整个热区缩成一个点。
-
img.offsetWidth和img.naturalWidth的比值才是横向缩放比,offsetHeight / naturalHeight是纵向缩放比 - 多边形的每个
x和y都要分别乘对应方向缩放比,不能统一用一个 scale - 如果图片被拉伸(比如宽高比失真),
scaleX !== scaleY,必须分开处理,否则圆形变椭圆、矩形变形
监听 resize 和 load 是必须的两步
只监听 window.resize 不够:图片可能懒加载、动态插入、或首次渲染时还没加载完成,load 事件才能拿到准确的 naturalWidth 和 offsetWidth。
- 必须同时绑定:
img.addEventListener('load', updateCoords)和window.addEventListener('resize', updateCoords) - 避免重复绑定:用
once: true或手动removeEventListener控制生命周期 - 更新前先检查
img.naturalWidth > 0,防止未加载完就读取为 0 导致除零或坐标归零
解析和重写 coords 字符串的实操要点
area.coords 是只读字符串,不能直接修改;必须解析、换算、再拼回字符串赋值。不同 shape 格式差异大,不能一锅炖。
-
shape="rect"→ 解析为[x1, y1, x2, y2],全部 4 个值都要缩放:x1 *= scaleX,y1 *= scaleY,x2 *= scaleX,y2 *= scaleY -
shape="circle"→ 解析为[cx, cy, r],cx和r用scaleX,cy用scaleY(半径也要缩放,否则小图上圆变大) -
shape="poly"→ 按对拆分:coords.split(',').map(Number),然后每对[i], [i+1]分别乘scaleX和scaleY,最后.join(',') - 别信“四舍五入”:保留 1 位小数即可(
Math.round(val * 10) / 10),整数反而容易因浮点误差错位
移动端最小热区与 touch-action 适配
iOS Safari 对小于 44×44px 的 area 点击极其不敏感,哪怕视觉上能看见,手指点下去大概率无响应。
- 换算后检查每个热区的最小包围尺寸:矩形看
x2-x1和y2-y1,圆形看2*r,多边形算 bounding box - 若换算后尺寸
- 给
img加style="touch-action: manipulation",减少 iOS 300ms 延迟,提升点击反馈感 - 别依赖
hover:移动端没有 hover 状态,所有高亮/反馈必须靠 JS 切 class 或操作area的title+aria-label
最常被忽略的一点:当图片被包裹在 picture、figure 或 Shadow DOM 中时,usemap 会失效——<map></map> 必须和 <img> 在同一 DOM 树层级,且不能被隔离作用域截断。调试时先确认右键图片能否在开发者工具中高亮到对应 <map></map> 元素,再往下查坐标逻辑。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











