检测鼠标指针移动离开页面


本文将介绍一种方法用于检测鼠标指针在页面中移动时,判断是否离开页面 👉

relatedTarget

W3C在 mouseovermouseout 事件中添加了 relatedTarget 属性。relatedTarget 属性返回与事件的目标节点相关的节点元素。

  • 对于 mouseover 事件来说,该属性表示来自哪个元素
  • 对于 mouseout 事件来说,该属性表示去往的那个元素

对于其他类型的事件来说,这个属性没有用。
而Microsoft添加了两个属性:

  • fromElementmouseover 事件中表示鼠标来自哪个元素
  • toElementmouseout 事件中指向鼠标去往的那个元素

跨浏览器脚本:

  • 如果你想知道鼠标来自哪个元素(mouseover 事件):

    1
    2
    3
    4
    function doSomething(e) {
    if (!e) var e = window.event;
    var relTarg = e.relatedTarget || e.fromElement;
    }
  • 如果你想知道鼠标去往哪个元素在(mouseout 事件):

    1
    2
    3
    4
    function doSomething(e) {
    if (!e) var e = window.event;
    var relTarg = e.relatedTarget || e.toElement;
    }

mouseover, mouseout, mouseenter, mouseleave

关于鼠标移动,有两组容易混淆的事件:

  • mouseover, mouseout: 事件会冒泡
  • mouseenter, mouseleave: 不会冒泡

如下例子:

  • 当鼠标移动进入 outer 元素,会触发 outer 元素的 mouseover, mouseenter 事件;
  • 当鼠标从 outer 元素移动进入 inner 元素,会触发 inner 元素的 mouseover, mouseenter 事件;同时会触发 outer 元素的 mouseover 事件

检测光标移动离开页面

通过 mouseout 鼠标事件,判断鼠标去往哪个元素

1
2
3
4
5
6
7
document.body.addEventListener('mouseout', (evt) => {
if (!evt) var evt = window.event
var to = evt.relatedTarget || evt.toElement
if (!to || to.nodeName == "HTML") {
alert("left window");
}
})

检测鼠标指针移动离开页面的应用的例子:拖拽一个DIV节点,在鼠标移动离开页面后,应该停止拖拽

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<html>
<head>
<meta charset="UTF-8">
<title>拖拽实现</title>
<style>
.block {
position: absolute;
left: 100px;
top: 100px;
height: 100px;
width: 40px;
height: 40px;
background: red;
}
</style>
</head>
<body>
<div class="block"></div>
<script>
var blcokEle = document.querySelector(".block")
var blockCurrPos = {x: -1, y: -1} // block element current position
var mouseStartPos = {x: -1, y: -1} // mouse start position
var canDrag = false
blcokEle.addEventListener('mousedown', (evt) => {
canDrag = true
let rect = blcokEle.getBoundingClientRect()
Object.assign(blockCurrPos, {x: rect.left, y: rect.top})
})
blcokEle.addEventListener('mouseup', (evt) => {
canDrag = false
})
document.body.addEventListener('mousedown', (evt) => {
if (!canDrag) { return }
Object.assign(mouseStartPos, {x: evt.clientX, y: evt.clientY})
})
document.body.addEventListener('mousemove', (evt) => {
if (!canDrag) { return }
var deltaX = evt.clientX - mouseStartPos.x
var deltaY = evt.clientY - mouseStartPos.y
blockCurrPos.x += deltaX
blockCurrPos.y += deltaY
mouseStartPos = {
x: evt.clientX,
y: evt.clientY
}
blcokEle.style['left'] = `${blockCurrPos.x}px`
blcokEle.style['top'] = `${blockCurrPos.y}px`
})
document.body.addEventListener('mouseout', (evt) => {
if (!canDrag) { return }
var to = evt.relatedTarget || evt.toElement;
if (!to || to.nodeName == "HTML") {
// stop your drag event here
canDrag = false
}
})
</script>
</body>
</html>

参考链接

How can I detect when the mouse leaves the window?