为什么 mousemove 事件在元素外还会触发?
我给一个 div 绑定了 mousemove 事件,但鼠标移出这个 div 后事件还在不断触发,这不应该啊?不是只有在元素内部才会触发吗?
我试过用 event.target 检查,发现有时候 target 是子元素,但即使完全移出容器区域,mousemove 还是会进来。是不是我哪里理解错了?
<div id="box" style="width: 200px; height: 200px; background: lightblue;">
<span>Move me</span>
</div>
<script>
document.getElementById('box').addEventListener('mousemove', (e) => {
console.log('moving', e.clientX, e.clientY);
});
</script>
mousemove事件会在鼠标移动时持续触发,而且它会冒泡到父元素。也就是说,即使鼠标已经移出了你的
要解决这个问题,我们需要检查事件的实际触发位置。event.target是实际触发事件的元素,而event.currentTarget才是绑定事件的元素。我们可以这样修改代码:
不过这样只能解决子元素的问题,如果鼠标完全移出整个元素区域还会触发,那可能是浏览器的事件处理机制导致的。更保险的做法是用mouseenter和mouseleave配合:
之所以会出现这个现象,是因为浏览器的事件系统设计就是这样的。mousemove事件本质上是全局的,只是我们通常把它绑定在特定元素上而已。当鼠标移动时,浏览器会持续发送这些事件,直到你明确告诉它停止。
我之前也被这个坑过,调试了半天才发现是事件冒泡在作怪。现在遇到这种需求都会直接用mouseenter/mouseleave来划清边界,这样逻辑更清晰。