mouseenter 与 mouseover 的区别与应用

221 阅读1分钟

一、事件介绍

  • mouseover:在鼠标首次移动到元素的激活区域内时,在该元素上触发。
  • mouseout:在鼠标移动至元素或其子元素之外时,会在该元素上触发;鼠标移动至元素或其子元素之外时,会在该元素上触发。
  • mouseenter:在鼠标首次移动到元素的激活区域内时,在该元素上触发。
  • mouseleave:在鼠标移出某个元素时被触发。

其中,mouseovermouseout 事件可以搭配使用,而 mouseentermouseleave 事件也可以搭配使用。

二、可以互换场景

当绑定事件的元素没有子元素时,使用 mouseover 和 mouseout 事件的效果是相同的。

<div id="parent" style="width: 150px;height: 150px;border: 1px solid red;"></div>
<div id="child" style="width: 150px;height: 150px;border: 1px solid blue;"></div>
<script>
    const parent = document.getElementById("parent");
    const child = document.getElementById("child");

    parent.onmouseover = () => {
        console.log("onmouseover")
    }
    parent.onmouseout = () => {
        console.log("onmouseout")
    }

    child.onmouseenter = () => {
        console.log("onmouseenter")
    }
    child.onmouseleave = () => {
        console.log("onmouseleave")
    }
</script>

当鼠标从上到下一次划过两个元素,输出结果为

<!--鼠标移入-->
onmouseover
<!--鼠标移出-->
onmouseout

<!--鼠标移入-->
onmouseenter
<!--鼠标移出-->
onmouseleave

三、不可互换场景

当元素存在子元素时,mouseovermouseout 事件的行为与 mouseentermouseleave 事件不同,不能进行互换。

3.1 mouseover 与 mouseout

<div id="parent" style="width: 300px;height: 300px;border: 1px solid red;position: relative;">
    <div id="child"
        style="width: 150px;height: 150px;border: 1px solid blue;position:absolute;left:  75px;top: 75px;">
    </div>
</div>
<script>
    const parent = document.getElementById("parent");
    const child = document.getElementById("child");

    parent.onmouseover = () => {
        console.log("parent-onmouseover")
    }
    parent.onmouseout = () => {
        console.log("parent-onmouseout")
    }

    // 对比更明显
    // child.onmouseover = (event) => {
    //     console.log("child-onmouseover")
    // }
    // child.onmouseout = (event) => {
    //     console.log("child-onmouseout")
    // }
</script>

当鼠标从上到下一次划过两个元素,输出结果为

<!--1.鼠标移入父元素-->
parent-onmouseover
<!--2.鼠标移出父元素->移入子元素-->
parent-onmouseout
<!--3.鼠标移入子元素事件冒泡到父元素-->
parent-onmouseover
<!--4.鼠标移出子元素事件冒泡到父元素-->
parent-onmouseout
<!--5.鼠标移入父元素-->
mouseover.html:38 onmouseover
<!--6.鼠标移出父元素-->
parent-onmouseout

3.2 mouseenter 与 mouseleave

 <div id="parent" style="width: 300px;height: 300px;border: 1px solid red;position: relative;">
    <div id="child"
        style="width: 150px;height: 150px;border: 1px solid blue;position:absolute;left:  75px;top: 75px;">
    </div>
</div>
<script>
    const parent = document.getElementById("parent");

    parent.onmouseenter = () => {
        console.log("parent-onmouseenter")
    }
    parent.onmouseleave = () => {
        console.log("parent-onmouseleave")
    }

</script>

当鼠标从上到下一次划过两个元素,输出结果为

<!--1.鼠标移入父元素-->
parent-onmouseenter
<!--2.鼠标移出父元素-->
parent-onmouseleave

3.3 输出结果原因分析

单个 mouseover 事件被发送到 DOM 树最深的元素中,然后它会按层次结构冒泡,直到它被处理程序取消或者到达根元素。

3.4 mouseenter 优势

  • 当层次结构很深,发送到 mouseover 事件可能相当多,并导致严重的性能问题。在这种情况下,最好是监听 mouseenter 事件。
  • 当层次结构很深,mouseover 事件监听触发很多次,mouseenter 相当于进行事件委托