题目:mouseenter vs mouseover


1. 事件冒泡行为的区别

核心记忆点:
  • mouseenter
    • ❌ 不冒泡(和 mouseover 不一样)
    • 进入元素自身时才触发
    • 从子元素进入父元素时触发一次,进入子元素 不影响 父元素
  • mouseover
    • ✅ 会冒泡
    • 鼠标进入元素或其子元素时都会触发
    • 移动到不同子元素时,父元素也会多次触发

2. 触发范围区别

  • mouseenter
    • 只在目标元素范围内触发一次
    • 鼠标在内部移动或到子元素时不会再次触发
  • mouseover
    • 从父到子,子到父过程中都可能触发
    • 鼠标从一个子元素移动到另一个子元素时,父元素会重复触发

3. relatedTarget 属性区别

属性 含义
event.relatedTarget 鼠标进入时:它指向“之前所在的元素”
鼠标离开时:它指向“要去的那个元素”
  • mouseentermouseover 都有这个属性。
  • 如果 relatedTarget 是某个子元素,mouseenter 不会因此触发父元素事件,而 mouseover 会触发并冒泡。

4. 代码对比实验

我们写一个简单的 DOM:

<!DOCTYPE html>
<html>
<head>
    <style>
        .parent {
            width: 300px;
            height: 200px;
            background-color: lightblue;
            padding: 20px;
        }
        .child {
            width: 150px;
            height: 100px;
            background-color: lightcoral;
        }
        .log {
            margin-top: 20px;
            height: 200px;
            overflow-y: auto;
            border: 1px solid #ccc;
            padding: 10px;
        }
    </style>
</head>
<body>
    <div id="parent" class ="parent">
        Parent
        <div id="child" class = "child">
          Child
        </div>
      </div>
      <div id = "log" class ="log"></div>
      <script>
        const parent = document.getElementById('parent');
        const child = document.getElementById('child');
        const log = document.getElementById('log');
      
        parent.addEventListener('mouseenter', () => {
          log.innerHTML += `mouseenter → parent<br>`;
        });
      
        parent.addEventListener('mouseover', () => {
            log.innerHTML += `mouseover → parent<br>`;
        });
      
        child.addEventListener('mouseenter', () => {
            log.innerHTML += `mouseenter → child<br>`;
        });
      
        child.addEventListener('mouseover', () => {
            log.innerHTML += `mouseover → child<br>`;
        });
      </script>
</body>
</html>
测试步骤(结果参考):
  1. 鼠标进入父元素空白区

    mouseenter → parent
    mouseover → parent
    

    在这里插入图片描述

  2. 鼠标从父元素空白区移到子元素

    mouseenter → child
    mouseover → child
    mouseover → parent   // 因为事件冒泡
    
  3. 鼠标在子元素内移动(没有跨越边界)

    • mouseenter 不触发
    • mouseover 可能触发(但同一元素内部小挪动不会触发)
  4. 鼠标移出父元素

    • 对应有 mouseleavemouseout 事件

5. Mermaid 图示解析事件流

mouseover 冒泡过程
鼠标移动到 Child
触发 Child mouseover
事件冒泡
父元素 parent 也触发 mouseover
mouseenter 处理过程
鼠标移动到 Child
只触发 Child mouseenter
父元素 parent 不触发 mouseenter

6. 使用场景对比

mouseenter

✅ 适合一次性进入检测(不关心子元素)
例子:

element.addEventListener('mouseenter', () => {
  tooltip.show();
});
mouseover

✅ 适合需要检测“进入任意子区域”的情况
例子:

element.addEventListener('mouseover', (e) => {
  e.target.style.background = 'yellow';
});

7. 总结表格

对比项 mouseenter mouseover
冒泡 ❌ 不冒泡 ✅ 会冒泡
子元素影响 不影响父元素 父元素也会触发
触发频率 进入元素一次 子元素切换也可能多次触发
常用场景 首次进入检测 动态样式或子元素 hover 检测
可替代关系 可用 mouseover + stopPropagation 实现 不能完全替代 mouseenter 的一次性进入

📌 面试答题建议:

mouseenter 不冒泡,只在元素首次进入时触发;mouseover 会冒泡,进入元素及其子元素时都会触发。mouseenter 更适合首次进入检测,mouseover 适合涉及子元素 hover 的情况。
个人见解:英文字面意思:mouseEnter注重enter,就是进入元素,所以不冒泡,首次进入触发。mouseOver注重Over,子元素被父元素包含,所以进入子元素也算在父元素上面。所以会冒泡且会一直触发


更多推荐