最近在敲代码的时候遇到关于JavaScript事件中求各种长宽,涉及到event中各种x/y,所以尝试做一些梳理。
这里说的event是指js中鼠标事件event的实例属性,而各种x/y就是指以下这些:
1 | e.clientX/e.clientY |
关于各种x/y属性的描述
在网上找了一些资料,对于这些属性都有描述。http://www.w3school.com.cn w3c给出了clientX/Y跟screenX/Y的描述,不过为了统一,我选择了阮一峰的一份JavaScript教程(https://wangdoc.com/javascript/events/mouse.html) 中的描述:
1 | MouseEvent.clientX属性返回鼠标位置相对于浏览器窗口左上角的水平坐标(单位像素) |
layerX/e.layerX
跟x/y
则没有找到比较权威的描述。
这些描述看完还是有点稀里糊涂的,不过可以看出,这些属性的值都是相对的,是有参考坐标的,比如浏览器,屏幕,目标节点,文档等。所以我们就试试在代码中获得更深入的理解。
代码实现实例属性
这里尝试做一个简单的演示项目,body中如下结构:
1 | <div class="canvas-wrapper"> |
div#container
元素是作为鼠标事件的目标节点,而canvas
画布则是用于绘出点击事件的坐标跟垂直线。
1 | * { |
由于这几个实例属性中有一些是涉及页面可视,所以给div#container
元素绝对定位,脱离文档流;为了页面可以上下左右滚动,所以body
跟canvas
元素的尺寸都很大。
而且为了减少盒模型的影响,所以设置了box-sizing: border-box;
js逻辑部分,给div#container
添加鼠标点击事件,回调函数中返回event,把event中的这些关于x/y的实例属性通过new传入一个位置构造函数的实例中,通过实例来绘出点击点跟各个x/y属性的线。
x/y各属性的表现梳理
这张截图是在浏览器向左向下滚动后(浏览器的上边贴着绿色线,浏览器的左边贴着绿色线),点击(点击点中心为黑点中心)触发事件得到的绘图。
clientX
/clientY
& x
/y
clientX
/clientY
在点击事件触发时是等于点击点到浏览器的上边跟左边,说明 clientX
/clientY
的参考坐标轴是沿着浏览器的上边为x轴,浏览器的左边为y轴 。跟目标节点的border
,margin
跟padding
没有关系。
相同的x
/y
在表现上也一样。不过最好使用的时候使用前者。
layerX
/layerY
layerX
/layerY
在点击事件触发之后显示出来是点击点到目标节点的边界,而且是在目标节点的边框上。目标节点的样式是有添加border
跟padding
样式的,而这个属性绘出的线跟目标节点的边框相交但不超出,说明 layerX
/layerY
的参考坐标轴是沿着目标节点的上边界(有边框则是沿着上边框)为x轴,目标节点的左边界(有边框则是沿着左边框)为y轴 。跟目标节点的margin
,页面的可视范围没有关系。
offsetX
/offsetY
offsetX
/offsetY
跟layerX
/layerY
很接近,但是它跟目标节点的边框没有相交,也就是当目标节点没有边框的情况下,offsetX
/offsetY
跟layerX
/layerY
的值是相等的。offsetX
/offsetY
的参考坐标轴是沿着目标节点的上边界为x轴,目标节点的左边界为y轴 。跟目标节点的margin
,页面的可视范围没有关系。
pageX
/pageY
pageX
/pageY
在点击事件触发之后显示出来是点击点到文档页面的边界,及时是页面发生了滚动,这个属性仍然显示的是点击点在文档页面的相对位置。所以 pageX
/pageY
的参考坐标轴是沿着文档页面的上边界为x轴,文档页面的左边界为y轴 。跟目标节点,页面的可视范围没有关系。
screenX
/screenY
screenX
/screenY
代码中没有绘制,原因在于这个属性的坐标是整个屏幕,跟浏览器无关,所以无法绘制展示出来。
上述就是鼠标事件event中关于x/y属性的梳理。文中的代码已上传github:
https://github.com/listentolife/mouseEventPositionAttributes