在前端交互开发中,获取鼠标位置是实现拖拽、点击判断、悬浮提示等功能的基础,js提供了多种方式获取不同参考系下的鼠标坐标,核心是通过事件对象的相关属性获取。

基础概念:事件对象与坐标属性
当鼠标在页面上触发点击、移动等事件时,事件回调函数会接收一个event对象,该对象包含了鼠标相关的所有信息,其中常用的坐标属性如下:
- clientX/clientY:鼠标相对于浏览器可视窗口左上角的水平和垂直坐标,不包含滚动条的滚动距离
- pageX/pageY:鼠标相对于整个文档页面左上角的水平和垂直坐标,包含滚动条的滚动距离
- offsetX/offsetY:鼠标相对于触发事件的目标元素左上角的水平和垂直坐标
- screenX/screenY:鼠标相对于用户屏幕左上角的水平和垂直坐标
不同场景的获取方法
1. 获取相对于浏览器窗口的位置
如果需要获取鼠标在当前可视窗口内的位置,直接使用clientX和clientY即可,适合实现窗口内的悬浮定位功能。
// 监听鼠标移动事件获取窗口内坐标
document.addEventListener('mousemove', function(event) {
// 获取相对于浏览器可视窗口的坐标
const x = event.clientX;
const y = event.clientY;
console.log('窗口内坐标:X=' + x + ', Y=' + y);
});
2. 获取相对于整个页面的位置
当页面存在滚动条,需要获取鼠标相对于整个文档顶部的位置时,使用pageX和pageY,这两个属性会自动加上滚动条的滚动距离。
// 监听点击事件获取页面坐标
document.addEventListener('click', function(event) {
// 获取相对于整个文档页面的坐标
const pageX = event.pageX;
const pageY = event.pageY;
console.log('页面坐标:X=' + pageX + ', Y=' + pageY);
});
3. 获取相对于目标元素的位置
如果只需要获取鼠标相对于某个具体元素左上角的位置,使用offsetX和offsetY,适合实现元素内的拖拽、点击区域判断等功能。
// 获取id为target的元素
const targetElement = document.getElementById('target');
// 监听目标元素的鼠标事件
targetElement.addEventListener('mousemove', function(event) {
// 获取相对于目标元素的坐标
const offsetX = event.offsetX;
const offsetY = event.offsetY;
console.log('相对于目标元素坐标:X=' + offsetX + ', Y=' + offsetY);
});
属性对比与注意事项
不同坐标属性的适用场景不同,我们可以通过下表快速区分:
| 属性名 | 参考原点 | 是否包含滚动距离 | 适用场景 |
|---|---|---|---|
| clientX/clientY | 浏览器可视窗口左上角 | 否 | 窗口内悬浮定位、可视区域交互 |
| pageX/pageY | 整个文档页面左上角 | 是 | 全页面位置记录、滚动场景下的坐标获取 |
| offsetX/offsetY | 触发事件的元素左上角 | 否 | 元素内交互、拖拽、点击区域判断 |
| screenX/screenY | 用户屏幕左上角 | 否 | 多屏幕场景下的坐标获取 |
需要注意,offsetX和offsetY在部分旧版本浏览器中存在兼容性问题,如果需要兼容旧环境,可以通过计算元素的位置和clientX的差值来获取相对坐标:
function getOffsetPosition(event, element) {
// 获取元素相对于可视窗口的位置
const rect = element.getBoundingClientRect();
// 计算相对于元素的坐标
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
return { x, y };
}
const box = document.getElementById('box');
box.addEventListener('click', function(event) {
const pos = getOffsetPosition(event, box);
console.log('兼容方式获取相对坐标:X=' + pos.x + ', Y=' + pos.y);
});
常见问题解答
很多开发者会遇到获取到的坐标值为undefined的情况,通常是因为没有正确获取事件对象,在IE旧版本浏览器中,事件对象需要通过window.event获取,兼容写法如下:
document.addEventListener('mousemove', function(event) {
// 兼容旧版本IE浏览器获取事件对象
const e = event || window.event;
const x = e.clientX;
const y = e.clientY;
console.log('兼容后坐标:X=' + x + ', Y=' + y);
});
另外,如果需要在触摸设备上获取触摸位置,对应的属性是touches[0].clientX和touches[0].clientY,和鼠标事件的属性逻辑类似,只是获取方式略有不同。