在JavaScript中,存在着事件对象,事件对象回记录事件触发时候的相关信息,比如鼠标点击事件就会记录鼠标点击时候的的位置相关信息,而这里又存在着几个个比较常用的坐标属性,它们是
offsetX/offsetY
、pageX/pageY
、layerX/layerY
、screenX/screenY
以及clientX/clientY
,现在就来简单介绍一下这几个属性吧。
offsetX/offsetY、pageX/pageY以及clientX/clientY
先康康MDN官网对这几个属性的定义
offsetX/offsetY
:MouseEvent 接口的只读属性offsetX/offsetY
规定了事件对象与目标节点的内填充边(padding edge)在 X/Y 轴方向上的偏移量。——(MDN-MouseEvent.offsetX)pageX/pageY
:pageX/pageY
是一个由MouseEvent接口返回的相对于整个文档的x/y坐标以像素为单位的只读属性。——(MDN-MouseEvent.pageX)clientX/clientY
:MouseEvent.clientX/MouseEvent.clientY 是只读属性, 它提供事件发生时的应用客户端区域的水平/垂直坐标 (与页面坐标不同)。——(MDN-MouseEvent.clientX)
简单整理了一下可以这样理解
offsetX/offsetY
:返回的是点击时候相对点击的元素左上角的相对位置(包含外边距)的坐标pageX/pageY
:返回的是整个文档的坐标,如果此时页面比较长可以获取文档中鼠标的坐标clientX/clientY
:返回的是鼠标点击的时候光标浏览器可视范围相对左上角的坐标
下面就来验证一下:
首先准备这样一个页面
CSS:
|
|
HTML:
|
|
现在页面上看起来是这样的
给document
对象添加一个点击事件
|
|
现在点击页面上的这里
输出:
- clientX:
18
clientY:18
- offsetX:
0
offsetY:0
- pageX:
18
pageY:18
可以看到当点击此处的时候,因为点击的是test盒子左上角的原点,所以offsetX
和offsetY
输出的是点击时候相对点击的元素左上角的相对位置(注:test盒子自身有内边距(padding
),offsetX和offsetY都是将内边距包含在内的),所以均输出0
而clientX/clientY
和pageX/pageY
输出的均为18px,这里可以通过之前设置的css进行计算
首先body
元素本身就有外边距(margin
),外边距(margin
)的值为8px,如下图
而test盒子本身的边框为10px,此时点击test盒子自身的左上角,对应的clientX/clientY
以及pageX/pageY
输出的值就是8+10=18px
验证成功!
但是此时还没看出这两个属性的区别,现在再准备一个测试用的div盒子,对应的CSS和HTML如下:
CSS:
|
|
HTML:
|
|
现在页面如大致结构下图所示:
现在点击id为absolute的盒子的边宽的左上角
此时输出的值为:
- clientX:
500
clientY:300
- offsetX:
-10
offsetY:-10
- pageX:
500
pageY:1500
pageX/pageY
的值是如何得到的:
此时用绝对定位将元素定位在top: 1500px left: 500px
的位置上,pageX/pageY
返回的是整个文档的坐标,pageX/pageY
对应的值也是500/1500
clientX/clientY
的值是如何得到的:
clientX/clientY
返回的是浏览器可视窗口的坐标,在水平距离上clientX
的返回值与pageX
一致,而垂直距离可以使用像素的距离计算出来
首先用截图软件看下此时id为absolute的元素左上角的坐标
然后看下浏览器可视窗口上边界的坐标
将Y轴上的坐标做个相减461-161=300
,验证成功,clientX/clientY
以及pageX/pageY
的结果均符合预期。
如果对上面说的有不理解的地方可以参考下面这张图:
至于此时的offsetX/offsetY
的值均为-10
是因为offsetX/offsetY
只计算包含到内边距(padding
)的距离而边框(border
)在内边距之外,所以返回的自然就是负数了,而此元素的边框(border
)又为10px,所以返回的值就是-10
了。
screenX/screenY
screenX/screenY 是只读属性,他提供了鼠标相对于屏幕坐标系的水平偏移量。——(MDN-MouseEvent.screenX)
可以简单理解为下面这句话:
screenX/screenY
返回的是鼠标点击的时候光标相对屏幕左上角的坐标
验证:
准备下面一段js代码
|
|
现在在页面上点击任意一点
输出:
- screenX:
521
screenY:401
这个时候打开截图工具查看下鼠标光标对应的坐标
可以看到与js代码输出的结果是完全一致的。
layerX/layerY
首先看下MDN官方对于此属性的定义
layerX/layerY是只读属性,返回点击的目标对象相对于当前层的水平/垂直坐标。——(MDN-MouseEvent.layerX)
简单可以理解为:
- 返回相对点击的元素相对于其父级元素(有定位属性)的坐标
- 如果点击的元素以及父级元素都没有定位属性,那就返回相对于body标签的坐标
- 如果点击的元素自身有定位属性返回的就是相对于自身的坐标
下面就来验证一下:
首先准备一个测试页面,其对应的CSS和HTML如下:
CSS:
|
|
HTML:
|
|
给document
对象添加一个点击事件
|
|
如果点击的元素以及父级元素都没有定位属性,那就返回相对于body标签的坐标
现在点击id为test2元素的左上角
输出数据:
- layerX:
36
layerY:36
此处的36是这样的来的,如下图所示
当元素的父级有定位属性时,以父级的左上角为原点:
修改CSS:
|
|
和刚才一样点击id为test2元素的左上角,输出:
- layerX:
28
layerY:28
此时因为test2的父级元素test1有了定位属性,所以layerX/layerY
输出的坐标就变为相对父级元素的左上角为原点的坐标。
如果点击的元素自身有定位属性返回的就是相对于自身的坐标
再次修改CSS:
|
|
和刚才一样点击id为test2元素的左上角,输出:
- layerX:
0
layerY:0
此时test2自身有了定位属性,所以layerX/layerY
输出的坐标就变为相对自身元素左上角为原点的坐标。
总结
offsetX/offsetY
:返回的是点击时候相对点击的元素左上角的相对位置(包含外边距)的坐标。pageX/pageY
:返回的是整个文档的坐标,如果此时页面比较长可以获取文档中鼠标的坐标。clientX/clientY
:返回的是鼠标点击的时候光标浏览器可视范围相对左上角的坐标。screenX/screenY
:返回的是鼠标点击的时候光标相对屏幕左上角的坐标。layerX/layerY
:往上找有定位属性的父元素的左上角(自身有定位属性的话就是相对于自身),都没有的话,就是相对于body的左上角的坐标。