写点什么

Web 前端入门:JavaScript 鼠标事件 (mouse) enter/leave 和 over/out 区别

  • 2025-07-09
    福建
  • 本文字数:1942 字

    阅读完需:约 6 分钟

题外话


在考察事件基础的时候,会经常被问及 clickmousedownmouseup 它们三者执行的先后顺序是怎样的?


如果平时没太注意,这细节可能就会忽略,毕竟很少会在同一个元素上面同时绑定这三个事件~~

直接上示例:

<div class="c">测试点击事件</div>
<script> (() => { const c = document.querySelector('.c') c.addEventListener('click', () => { console.log('click') }) c.addEventListener('mousedown', () => { console.log('mousedown') }) c.addEventListener('mouseup', () => { console.log('mouseup') }) })()</script>
复制代码


实际控制台输出:



而且 click 事件鼠标在元素上点击之后,再按住鼠标移开元素,此时并不会触发 click 事件,仅 mousedown 事件被触发了。这里就有一个比较有意思的操作了,如果开发中想要用户无法取消事件,那就直接用 mousedown 事件吧~~


事件 enter/leave 和 over/out 区别


这两组事件都是鼠标进入元素和离开元素时触发,用文字描述的区别就是 over/out 这一组事件会冒泡,而 enter/leave 这组事件不会冒泡。


如果绑定事件没有子元素,其实两者没有任何区别,比如:


<style>  .c {    border: 1px solid #000;    padding: 8px;  }</style>
<div class="c">前端路引--事件测试</div>
<script> (() => { const c = document.querySelector('.c') c.addEventListener('mouseover', () => { console.log('mouseover') }) c.addEventListener('mouseout', () => { console.log('mouseout') }) c.addEventListener('mouseenter', () => { console.log('mouseenter') }) c.addEventListener('mouseleave', () => { console.log('mouseleave') }) })()</script>
复制代码


效果:



可以明显看到,这两组事件触发都是一样的,在鼠标移入和移除的时候都触发了。

但这里有一个细节:enter/leave 这组事件永远都是在 over/out 后面触发,不论代码的先后顺序,也不论是否是事件捕获!!


存在子元素时


上面事件看不出区别来,别急,来一个包含子元素的例子:

<style>  .bd {    border: 1px solid #000;    padding: 8px;  }</style>
<div id="container1" class="bd"> 外层 <div class="bd"> 内层 <div class="bd"> 最内层 <div class="bd"> 按钮 </div> </div> </div></div>
<script> (() => { const c = document.querySelector('#container1') c.addEventListener('mouseover', () => { console.log('mouseover') }) c.addEventListener('mouseout', () => { console.log('mouseout') }) c.addEventListener('mouseenter', () => { console.log('mouseenter') }) c.addEventListener('mouseleave', () => { console.log('mouseleave') }) })()</script>
复制代码


效果:



可以看到 over/out 这组事件,在鼠标每次进入子元素时候,都会触发父元素的 over/out 事件;而 enter/leave 这组事件只会在进入/离开父元素时候触发一次。

前面说了,over/out 是冒泡事件,那能不能通过 event.stopPropagation() 来阻止冒泡?

把所有事件都添加上 阻止传播 试试:


(() => {  const c = document.querySelector('#container1')  c.addEventListener('mouseover', (event) => {    event.stopPropagation()    console.log('mouseover')  })  c.addEventListener('mouseout', (event) => {    event.stopPropagation()    console.log('mouseout')  })  c.addEventListener('mouseenter', (event) => {    event.stopPropagation()    console.log('mouseenter')  })  c.addEventListener('mouseleave', (event) => {    event.stopPropagation()    console.log('mouseleave')  })  document.querySelectorAll('.bd').forEach((item) => {    item.addEventListener('mouseover', (event) => {      event.stopPropagation()    })    item.addEventListener('mouseout', (event) => {      event.stopPropagation()    })  })})()
复制代码


效果:



可以看到虽然 最内层 里面的元素移动不会触发顶层事件,但在 内层 和 外层 来回移动的时候,还是会触发事件冒泡。

可以理解为每个子元素都有物理空间,over/out 这组事件在父元素和子元素的物理空间来回移动的时候,还是会触发 over/out 事件。


写在最后


开发中需要根据需求选择合适的事件,一般情况 enter/leave 这组事件使用率相对而言较高一些。


文章转载自:前端路引

原文链接:https://www.cnblogs.com/linx/p/18972694

体验地址:http://www.jnpfsoft.com/?from=001YH

用户头像

还未添加个人签名 2025-04-01 加入

还未添加个人简介

评论

发布
暂无评论
Web前端入门:JavaScript 鼠标事件(mouse) enter/leave 和 over/out 区别_JavaScript_电子尖叫食人鱼_InfoQ写作社区