area标签无法直接绑定jQuery事件,应绑定到usemap关联的img上,通过坐标计算判断点击是否在rect/circle/poly区域内,需注意图片加载完成、移动端touch适配及poly射线法判断。

area 标签本身不支持直接绑定 jQuery 事件
直接对 <area> 元素调用 $('area').on('click', handler) 大概率无效——因为 <area> 必须嵌套在 <map> 中,且依赖 <img usemap> 才能激活交互区域,浏览器对它的事件捕获非常有限,原生只响应 click(部分浏览器连 mouseenter 都不触发)。
真正可行的做法是:把事件绑定到对应的 <img> 上,再通过坐标计算判断是否落在某个 <area> 范围内。
- 确保
<img>设置了usemap属性,且值与<map name="xxx">的name匹配 -
<area>必须有shape(rect、circle、poly)和coords,否则无法做坐标判断 - jQuery 事件委托(如
$(img).on('click', ...))比直接绑定更可靠,尤其在动态插入<map>时
用 jQuery 获取点击位置并匹配 rect/circle area
对 rect 和 circle 这类规则形状,手动解析 coords 并做简单数学判断即可,不需要引入额外库。
示例 HTML:
立即学习“前端免费学习笔记(深入)”;
<img src="plan.png" usemap="#floor-map" id="floor-img"> <map name="floor-map"> <area shape="rect" coords="10,20,110,120" data-id="room-a"> <area shape="circle" coords="200,150,30" data-id="exit"> </map>
对应 jQuery 处理逻辑:
$('#floor-img').on('click', function(e) {
const offset = $(this).offset();
const x = e.pageX - offset.left;
const y = e.pageY - offset.top;
<p>$('area').each(function() {
const $area = $(this);
const shape = $area.attr('shape');
const coords = $area.attr('coords').split(',').map(Number);</p><pre class='brush:php;toolbar:false;'>if (shape === 'rect') {
const [left, top, right, bottom] = coords;
if (x >= left && x <= right && y >= top && y <= bottom) {
console.log('hit rect:', $area.data('id'));
}
} else if (shape === 'circle') {
const [cx, cy, r] = coords;
const dx = x - cx, dy = y - cy;
if (dx*dx + dy*dy <= r*r) {
console.log('hit circle:', $area.data('id'));
}
}}); });
poly area 坐标判断要用点在多边形内算法
poly 的 coords 是一串交替的 x/y 坐标(如 "10,20,30,40,50,60"),不能靠矩形或圆公式判断,必须用射线法(Ray Casting)或叉积法。
建议直接使用轻量函数,比如这个无依赖的 isPointInPoly:
function isPointInPoly(x, y, coords) {
let inside = false;
for (let i = 0, j = coords.length - 2; i < coords.length; j = i, i += 2) {
const xi = coords[i], yi = coords[i+1];
const xj = coords[j], yj = coords[j+1];
const intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
}在上面的 click 回调里加一段:
else if (shape === 'poly') {
if (isPointInPoly(x, y, coords)) {
console.log('hit poly:', $area.data('id'));
}
}- 注意
coords必须是偶数长度数组,且按顺序成对(x,y,x,y...) - 多边形坐标必须是顺时针或逆时针闭合路径(首尾不必重复),否则射线法结果不可靠
- 如果
<area>数量多(>50),建议预计算 bounding box 做快速排除,避免每次都跑完整射线法
移动端 click 延迟和 touch 事件适配
在 iOS/Android 上,仅监听 click 会有约 300ms 延迟,且 <area> 在某些 WebView 中对 touchstart 完全无响应。
- 推荐同时绑定
click和touchend,并统一用e.preventDefault()防止双触发 - 不要用
touchstart—— 它在手指刚落下的瞬间触发,用户可能只是想滑动图片,不是点击 - 若图片可缩放或滚动,需监听
scroll或resize重新计算offset(),否则坐标会偏移 - Chrome Android 对
<area>的focus/blur支持极差,别试图做键盘导航
实际项目里最常被忽略的,是图片加载完成前就绑定事件——$(img).on('load', ...) 内执行坐标逻辑,或者用 $(document).ready() 加 img.complete 双保险。否则 offset() 可能为 0,所有坐标计算全错。



















