HOWTO · JavaScript
在 JavaScript 中跟踪鼠标位置
在本教程中,我们将了解如何在 JavaScript 中使用鼠标事件跟踪鼠标位置。
本页内容
为跟踪指针移动,可以为浏览器的 mousemove 事件注册回调。回调会接收一个 MouseEvent;应从该事件读取坐标属性,而不是另外维护指针状态。指针在窗口中移动时会触发此事件,因此处理函数可以在每次移动时读取最新位置。
监听鼠标移动事件 mousemove
事件监听器由事件类型和回调函数组成。在下面的浏览器示例中,window.addEventListener 会为 mousemove 注册 handleMouseMove,回调读取 pageX、pageY、clientX 和 clientY。属性名称区分大小写。mousemove 事件用于报告指针移动;页面加载或指针静止时都不会因此触发该事件。
下面的小型可运行示例展示了回调如何格式化事件值。示例中的普通对象只是用于说明属性名称的样例输入;在交互式页面中应使用浏览器提供的真实 MouseEvent。代码中的控制台标签保持英文原样,以便与示例输出对应。
运行此示例:
本节中的代码以及显示的标签或输出仍为英文。
function handleMouseMove(event) {
console.log(
`page: (${event.pageX}, ${event.pageY}); client: (${event.clientX}, ${event.clientY})`
);
}
handleMouseMove({ pageX: 120, pageY: 240, clientX: 120, clientY: 240 });
要体验浏览器中的交互,请使用这个独立页面。页面内容足够长,可以滚动;指针在页面上移动时,处理函数会记录两组坐标。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Mouse coordinates</title>
<style>
body { min-height: 1600px; font: 16px sans-serif; }
main { padding: 2rem; }
</style>
</head>
<body>
<main>
<h1>Move the pointer, then scroll</h1>
<p>Open the browser developer console to compare the coordinate pairs.</p>
</main>
<script>
window.addEventListener('mousemove', (event) => {
console.log(
`page: (${event.pageX}, ${event.pageY}); client: (${event.clientX}, ${event.clientY})`
);
});
</script>
</body>
</html>
如何选择页面坐标或视口坐标
pageX 和 pageY 以文档左上角为原点测量指针位置。它们包含文档的滚动偏移量,因此适合在读者滚动页面时仍需让位置对应文档内容的场景。例如,记录长文档中某个点的位置时,可以使用页面坐标。
clientX 和 clientY 以当前可见视口的左上角为原点进行测量。滚动不会改变这个原点。如果要定位或比较当前浏览器可见区域内的对象,例如自定义光标标记或视口叠加层,可以使用这组值。
这两组坐标属于不同的坐标空间,因此计算时应始终使用同一组。混用页面坐标和视口坐标会使结果产生与滚动偏移量相对应的位移。若要让某个元素跟随指针,还需要额外处理鼠标事件并编写元素定位逻辑;仅仅读取坐标不会移动元素。
滚动时比较 pageX 和 clientX
滚动前,文档原点与视口原点重合,因此水平坐标 pageX 和 clientX 相同,垂直坐标 pageY 和 clientY 也相同。移动指针并在控制台中查看两组坐标。第一张随附视图展示了滚动前的控制台。
向下滚动后,水平坐标通常仍然一致;垂直坐标 pageY 会包含滚动距离,而 clientY 仍以视口顶部为基准。两者的差值对应当前的滚动偏移量。第二张随附视图展示了滚动后的控制台。
如果要获取相对于当前可见区域的位置,请使用 clientX 和 clientY。如果要获取相对于文档的位置(包括滚动后的内容),请使用 pageX 和 pageY。如需了解更多浏览器鼠标事件,请参阅 MDN 鼠标事件参考。