You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

mouseenter与mouseleave在Safari、Edge及IE中失效问题求助

解决<area>元素鼠标事件在Safari/Edge/IE中失效的问题

嘿,我之前也踩过一模一样的坑!问题根源在于Safari、旧版Edge和IE对<area>元素的mouseenter/mouseleave事件支持非常差——要么完全不触发,要么触发逻辑和Chrome/Firefox完全不一致。下面给你几个靠谱的解决方案:

方案1:用mouseover/mouseout模拟mouseenter/mouseleave

mouseover和mouseout是所有浏览器都原生支持的事件,我们只需要通过判断relatedTarget过滤掉子元素冒泡的情况,就能完美模拟出mouseenter/mouseleave的行为:

var areas = document.getElementsByTagName('area');
for (var i = 0; i < areas.length; i++) {
    areas[i].addEventListener('mouseover', handleMouseOver);
    areas[i].addEventListener('mouseout', handleMouseOut);
}

// 模拟mouseenter逻辑
function handleMouseOver(e) {
    // 确认鼠标是从元素外部进入(area一般没有子元素,但保留判断更严谨)
    if (!e.currentTarget.contains(e.relatedTarget)) {
        console.log('mouseenter');
        // 这里替换成你原有的inArea业务逻辑
    }
}

// 模拟mouseleave逻辑
function handleMouseOut(e) {
    if (!e.currentTarget.contains(e.relatedTarget)) {
        console.log('mouseleave');
        // 这里替换成你原有的outArea业务逻辑
    }
}

方案2:绑定事件到对应的<img>元素(兼容性最强)

有些极端场景下,连mouseover在<area>上都不生效,这时候可以把鼠标事件绑定到关联的<img>上,通过elementFromPoint判断鼠标位置是否落在某个<area>范围内:

// 获取关联的img元素(需确保img有usemap属性关联map)
var mapImg = document.querySelector('img[usemap]');
// 记录当前hover的area,避免重复触发事件
var currentHoverArea = null;

mapImg.addEventListener('mousemove', function(e) {
    // 获取鼠标位置对应的DOM元素
    var hoveredElement = document.elementFromPoint(e.clientX, e.clientY);
    
    // 判断是否切换了hover的area
    if (hoveredElement.tagName === 'AREA' && hoveredElement !== currentHoverArea) {
        // 如果之前有hover的area,先触发leave事件
        if (currentHoverArea) {
            outArea.call(currentHoverArea);
        }
        currentHoverArea = hoveredElement;
        // 触发enter事件,用call让this指向当前area
        inArea.call(currentHoverArea);
    } 
    // 鼠标移出所有area的情况
    else if (currentHoverArea && hoveredElement.tagName !== 'AREA') {
        outArea.call(currentHoverArea);
        currentHoverArea = null;
    }
});

// 保留你原有的事件处理函数
function inArea() {
    console.log('mouseenter');
}

function outArea() {
    console.log('mouseleave');
}

额外检查项

别忘了确认你的<area>标签属性是否正确:

  • shape和coords必须匹配(比如rect需要4个数字,circle需要3个,poly需要偶数个坐标对)
  • coords里不能有多余符号,必须是纯数字用逗号分隔
  • 确保<img>的usemap属性和<map>的name/id完全对应

为什么会出现这个问题?

早期浏览器对<area>这类特殊元素的事件模型实现不完善,mouseenter/mouseleave是后来才加入的不冒泡事件,旧浏览器根本没实现这个逻辑,而mouseover/mouseout是更早的标准事件,兼容性覆盖更广。

内容的提问来源于stack exchange,提问作者Julie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:58:34