获取DOM元素事件位置信息的常用方法

在JavaScript的DOM操作中,我们经常需要获取元素或事件的宽高及定位信息。因此我们就需要用到一些属性来得到我们想要的信息。

Part1 client、scroll、offset元素属性的定义

在w3c的官方文档里,我们可以看到这几个属性都归类在HTML DOM元素对象的属性方法中,适用于所有HTML元素,都是只读属性。

1
2
3
4
5
6
7
8
element.clientHeight //在页面上返回内容的可视高度(不包括边框,边距或滚动条)
element.clientLeft //元素的左边框的宽度,若左边出现了垂直滚动条,也包含滚动条的宽度
element.offsetHeight //返回元素的高度,包括边框和填充,但不是边距
element.offsetLeft //获取边框相对于具有定位属性的父对象的左边距
element.scrollHeight //返回元素的整体高度(包括带滚动条的隐蔽的地方)
element.scrollLeft //滚动条卷去隐藏的距离

clientHeight、scrollHeight、offsetHeight的比较

client

client
clientHeight:可见区域的宽度,不包括boder的宽度,如果区域内带有滚动条,还应该减去横向滚动条不可用的高度,正常的是17px,其实就是滚动条的可滚动的部分了,其实clientHeightheight的高度差不多,如果不带滚动条的话他们的值都是一样的,如果带有滚动条的话就会比height值少17px;火狐与IE下均为一致。
注意,对于类型<i>,<code><span>这些内联元素,clientWidthclientHeight总是返回0。

scroll

scroll
scrollHeight:同样不包含border,由heightpadding相加。若包含滚动条,scrollHeight就是滚动条可滚动的距离。(heightpadding相加在减去滚动条的高度,默认为17px)。直观的说法就是元素的内容区域加上它的内边距再加上任何溢出内容的尺寸。当内容正好和内容区域匹配而没有溢出时,这些属性与clientWidth和clientHeight是相等的。但当溢出时,它们就包含溢出的内容,返回值比clientWidth和clientHeight要大。

offset

offset
offsetHeight:元素的offsetHeightw值包括该元素的边框,元素的垂直内边距,元素的水平滚动条(若出现水平滚动条),以及元素的样式高度。实际值为height + padding + border

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试代码</title>
<style>
div{
overflow: scroll; /*设置滚动条*/
position: absolute;
left: 1500px;
width: 300px;
height: 300px;
border: 5px solid #000;
padding: 10px;
margin: 20px;
}
</style>
</head>
<body>
<div></div>
<script>
var div = document.getElementsByTagName('div')[0];
console.log('clientWidth: '+ div.clientWidth);
//320 padding+width 有滚动条时 303 padding+width-scroll(默认17px)
console.log('clientLeft: '+ div.clientLeft);
//5 边框的宽度,有滚动条就加滚动条宽度
console.log('offsetWidth: '+ div.offsetWidth);
//330 boder + padding + width
console.log('offsetLeft: '+ div.offsetLeft);
//1520 获取边框相对于具有定位属性的父对象的左边距
console.log('scrollWidth: ' + div.scrollWidth);
//320 padding + width 有滚动条时 303 padding+width-scrollWidth(默认17px)
console.log('scrollLeft: ' + div.scrollLeft);
//0 滚动条卷去的部分
</script>
</body>
</html>

Part2 offset、client、screen、page在DOM事件中的定义

在文档中,以上4个属性都归类在DOM Event中,属于事件状态,需要与函数结合起来使用,函数不会在事件发生前执行。常见的事件有鼠标点击、键盘按下等,事件发生后,我们就能检测相应的属性。

screen

screenX:鼠标位置相对于用户屏幕水平偏移量,此时的参照点也就是原点是屏幕的左上角

client

clientX:跟screenX相比就是将参照点改成了浏览器内容区域的左上角,该参照点会随之滚动条的移动而移动,也就是说,他计算lefttop时直接忽略了滚动条的高和宽,它的参考点是浏览器可见区域的左上角,而不是页面本身的body左上角原点,计算数值和滚动条是否滚动没有关系,只是绝对的计算鼠标点距离浏览器内容区域的左上角的距离,忽略了滚动条的存在。

page

pageX:参照点是页面本身的body原点,而不是浏览器内容区域左上角,它计算的值不会随着滚动条而变动,它在计算时其实是以body左上角原点(即页面本身的左上角,而不是浏览器可见区域的左上角)为参考点计算的,这个相当于已经把滚动条滚过的高或宽计算在内了,所以无论滚动条是否滚动,他都是一样的距离值。

pageX = clientX + ScrollLeft(滚动条滚过的水平距离)
pageY = clientY + ScrollTop(滚动条滚过的垂直距离)

offset

offsetX:offsetX 表示鼠标指针位置相对于触发事件的对象x 坐标。不包含边框,所以可以为负值。


总结

在实际开发中,我们经常要使用以上的方法来获得我们需要的值。首先,我们应该注意每一种属性的区别,了解他们是如何计算出来的,不至于在开发中张冠李戴,出现错误。其次,以上各种属性在不同浏览器中也有兼容问题,也是我们必须要要小心的地方,因为你可能写对了名字,但是在这个浏览器中无效,那也是白忙活一场。
所以,在开发时,应尽量避免出现这些问题,多进行验证,这样才能保证代码的正确性。