coords 不支持百分比,仅接受整数像素值;必须用 JS 按 naturalWidth/naturalHeight 与 offsetWidth/offsetHeight 计算缩放比,分 shape 类型逐坐标缩放并 round 后赋值。

coords 为什么不能直接写百分比
浏览器根本不认 coords="10%,20%,80%,90%" 这种写法——它会静默忽略整个值,导致 area 完全失效。HTML 规范明确要求 coords 只接受逗号分隔的整数像素值,比如 "10,20,100,80"。这不是兼容性问题,而是硬性限制。哪怕你用 CSS 把图片缩放到 50%,coords 依然按原始尺寸(img.naturalWidth/naturalHeight)计算,坐标系不会自动缩放。
动态重设 coords 的核心逻辑
必须靠 JS 读取当前渲染尺寸与原始尺寸的比例,再逐个点缩放。关键不是“改宽高”,而是对齐坐标系:
-
img.naturalWidth和img.naturalHeight是图片真实像素尺寸,必须等img.onload后才能可靠读取 -
img.offsetWidth和img.offsetHeight是当前实际渲染尺寸,注意:要在图片 layout 完成后取(避免在DOMContentLoaded阶段就执行) - 缩放比例要分开算:
scaleX = offsetWidth / naturalWidth,scaleY = offsetHeight / naturalHeight;矩形、圆形、多边形的每个坐标都要按对应轴缩放 -
area.coords是只读字符串,需.split(',').map(Number)解析 → 缩放 →.join(',')赋回
不同 shape 的 coords 缩放要注意什么
shape 类型决定了 coords 的结构,缩放时不能一锅炖:
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
-
shape="rect":4 个值,顺序是x1,y1,x2,y2,偶数位(0、2)是 X 坐标,奇数位(1、3)是 Y 坐标 → 分别乘scaleX和scaleY -
shape="circle":3 个值,cx,cy,r→cx和cy乘对应缩放比,r要同时受两个方向影响,稳妥做法是取Math.min(scaleX, scaleY) * r防止拉伸变形 -
shape="poly":必须是偶数个数字,每对x,y为一个顶点 → 严格按索引奇偶分别缩放,错一位整个多边形就翻转 - 所有缩放结果必须
Math.round(),浏览器不接受小数坐标
监听时机和常见坑
最常出问题的地方不在算法,而在时机和边界条件:
立即学习“前端免费学习笔记(深入)”;
- 别在
DOMContentLoaded里直接操作 —— 图片可能还没加载完,naturalWidth是 0,缩放比变成NaN - 用
img.addEventListener('load', handler),且确保 handler 绑定到最终加载完成的img实例(尤其用了<picture>或srcset时) - 移动端屏幕旋转、横竖屏切换会触发
resize,但部分安卓 WebView 不触发,建议加ResizeObserver监听图片容器 - 如果页面有多个
map,记得用usemap的值精确匹配map[name],否则document.querySelectorAll('area')会抓到错误区域 - 缩放后
coords字符串里不能有空格,"100, 200"中的空格会导致第二值被截断,必须.join(',')无空格拼接
动态改 coords 看似只是字符串处理,但真正卡住人的永远是尺寸读取时机、shape 类型误判、以及缩放后没 round 导致坐标非法。这些点漏掉一个,热点就静默失效,连控制台都不会报错。


















