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

mouseenter事件进入带子元素容器时触发两次,如何实现单次触发?

问题原因

你遇到的mouseenter两次触发问题,核心是事件处理函数里修改了#demo的边框样式,导致元素的几何边界发生了变化:

  1. 初始状态下,#demo带有1px边框,鼠标停在#demo的底部边框区域时,仍属于#demo的范围,触发第一次mouseenter。
  2. 事件触发后,你将#demo的borderStyle设为none,边框直接消失。由于默认盒模型(content-box)下,border不属于元素设置的height/width范围,#demo的实际占用空间会瞬间缩小——之前鼠标所在的底部边框位置,立刻变成了#demo的外部区域。
  3. 当鼠标继续移动到内部的#test元素时,相当于从#demo外部重新进入元素,因此触发第二次mouseenter。
解决方案

提供几种可行的解决思路:

方法1:修改盒模型,避免元素尺寸突变

把#demo的盒模型改为border-box,这样边框会被包含在设置的height/width内,修改边框样式不会改变元素的整体尺寸:

#demo {
  box-sizing: border-box; /* 新增该行 */
  border: 1px solid gray;
  height: 60px;
  padding: 18px;
}

这种方式下,即使去掉边框,#demo的整体大小保持不变,鼠标不会因为边框消失而被“移出”元素,自然不会触发第二次事件。

方法2:调整边框修改的时机或逻辑

如果不需要动态移除边框,直接删掉事件里的this.style.borderStyle = 'none';即可。如果必须修改边框,可以换个时机(比如在mouseleave事件中恢复边框),或者通过其他样式属性(如透明度)来实现视觉效果,避免改变元素的几何边界。

方法3:添加标志位,限制重复触发

给元素设置一个状态标志,确保mouseenter在短时间内只执行一次:

const main = document.querySelector('#demo');
let isEntered = false;

main.addEventListener('mouseenter', function(e) {
  if (isEntered) return;
  isEntered = true;
  
  this.style.borderStyle = 'none';
  console.log('enter');
});

// 在鼠标离开时重置标志,同时可选恢复边框
main.addEventListener('mouseleave', function() {
  isEntered = false;
  this.style.borderStyle = 'solid';
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 09:07:14