一文弄清 clientX、pageX、offsetX 和 screenX

在平常浏览学习一些前端知识的时候,偶尔会涉及到一些与用户进行交互的小功能,需要获取用户鼠标的点击坐标,看着案例里有时会使用 clientXclientY,有时又使用的是 offsetXoffsetY 等,依葫芦画瓢,半懂不懂。本文就来总结归纳一下 clientXpageXoffsetXscreenX 之间的区别(clientYpageYoffsetYscreenY 则可照理类推)。

代码准备

首先明确一点,它们都是鼠标事件(MouseEvent)的属性,即当鼠标发生点击(click)或移动(mousemovemousedown等)时,浏览器会自动将MouseEvent传入到对应的事件监听回调中。

为了验证各个属性之间的区别,我准备了 2 个宽高均为 100px 的方块,其中黄色方块通过绝对定位布置在 left: 100pxtop: 100px 的地方;为了产生水平和垂直滚动条,让蓝色方块绝对定位在了 left: 100%top: 100% 的位置。然后定义了鼠标移动事件,将各个属性展示出来:

下面就来具体说说各个属性,它们各自第一行的定义均引用自 MDN 文档:

clientX

MouseEvent.clientX 是只读属性,它提供事件发生时的应用客户端区域的水平坐标 (与页面坐标不同)。

clientX 是相较于客户端的,通常就是指浏览器的内容区域(窗口),或者比如码上掘金的这块显示区域,也可以看成是一个客户端。它的特点是 包括窗口自身控件和滚动条,比如当鼠标指针放在窗口右下角时,横向滚动条在最左边和最右边时,clientX 的值是一样的:

注意,这里说的不包括滚动条,不是指当鼠标指针放到垂直 滚动条上时,测不到正确的 clientX 数值,而是指无论是否存在水平 滚动条,不影响 clientX 的结果:

pageX

pageX 是一个由 MouseEvent 接口返回的相对于整个文档的 x(水平)坐标以像素为单位的只读属性。

pageX 的零点同 clientX 一样,也是在浏览器内容区域的最左边,但是它的值受到滚动条的影响。

  • 当水平滚动条位于最左边时,pageXclientX 一样大:
  • 当水平滚动条位于最右边时 pageX 就比 clientX 大,且刚好大了水平滚动的 100px 距离:

offsetX

MouseEvent 接口的只读属性 offsetX 规定了事件对象与目标节点的内填充边(padding edge)在 X 轴方向上的偏移量。

clientX 不同的点有 2 方面:

offsetX 受到滚动条的影响

当鼠标指针位于 2 个方块之外的浏览器内容区域内,并且不存在水平滚动条或水平滚动条在最左边时,offsetX 的值与 clientX 的值相同:

而当水平滚动条移到最右边时,可以看到 offsetX 要比 clientX 大,且刚好大了水平滚动的 100px:

offsetX 获取的是相对于触发事件的对象的 x 坐标

当鼠标指针位于蓝色方块内部时,可以看到 offsetX 的值仅为 25。虽然我们监听的是 document.onmousemove,但是由于事件的冒泡,触发 mousemove 事件的其实是蓝色方块,所以 offsetX 的值为相对于蓝色方块最左边的距离:

screenX

screenX 是 MouseEvent 的只读属性,提供鼠标在全局(屏幕)中的水平坐标(偏移量)

screenX 获取的是鼠标指针相对于整个屏幕的 x 坐标。所以当浏览器窗口没有铺满整个屏幕时,我把鼠标指针放在了浏览器内容区域的左上角位置,此时 clientXpageXoffsetX 都接近 0, 但 screenX 的值为 136:

注意,当使用了多显示屏时,水平对齐的屏幕会被视为单个设备。比如我就使用了双显示屏,副屏幕在主屏幕的左边。当我把浏览器放在副屏幕时,screenX 会是个负数:

相关推荐
lizz227613 分钟前
Babel插件手册
javascript
用户9385156350721 分钟前
从小米前端面试题,彻底搞懂闭包、作用域链与 useState 惰性初始化
前端·面试
粥里有勺糖1 小时前
视野修炼第133期 | Native 回春了?
前端·github·agent
aichitang20242 小时前
前端小skill
前端·人工智能·算法·ai·前端框架
前端·柱子2 小时前
q-floodfill白边锯齿?一招搞定抗锯齿边缘问题
前端·html·canva可画
葡萄城技术团队2 小时前
SpreadJS V19.2新特性揭秘:功能区键盘提示
前端
计算机魔术师3 小时前
AI 幻觉导致的错误情报险些引发美军拦截中国船只
前端
万物智能3 小时前
SARADC模数转换—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
前端·后端
VXbishe3 小时前
【课程设计】基于SpringBoot的乡村政务服务系统的设计与实现-计算机毕设77011
javascript·vue.js·spring boot·python·php·课程设计·政务
志尊宝3 小时前
Vue3 零基础每日笔记(037):动手封装 useMouse 与 useWindowSize——事件监听的标准模板
前端·javascript·vue.js·笔记·html5