搞清clientHeight、offsetHeight、scrollHeight、offsetTop、scrollTop

转载自:https://www.imooc.com/article/17571

网页可见区域高:document.body.clientHeight

网页正文全文高:document.body.scrollHeight
网页可见区域高(包括边线的高):document.body.offsetHeight
网页被卷去的高:document.body.scrollTop

屏幕分辨率高:window.screen.height

每个HTML元素都具有clientHeight offsetHeight scrollHeight offsetTop scrollTop 这5个和元素高度、滚动、位置相关的属性,单凭单词很难搞清楚分别代表什么意思之间有什么区别。通过阅读它们的文档总结出规律如下:
clientHeight和offsetHeight属性和元素的滚动、位置没有关系它代表元素的高度,其中:
clientHeight:包括padding但不包括border、水平滚动条、margin的元素的高度。对于inline的元素这个属性一直是0,单位px,只读元素。


图片描述

offsetHeight:包括padding、border、水平滚动条,但不包括margin的元素的高度。对于inline的元素这个属性一直是0,单位px,只读元素。


图片描述

接下来讨论出现有滚动条时的情况:
当本元素的子元素比本元素高且overflow=scroll时,本元素会scroll,这时:
scrollHeight: 因为子元素比父元素高,父元素不想被子元素撑的一样高就显示出了滚动条,在滚动的过程中本元素有部分被隐藏了,scrollHeight代表包括当前不可见部分的元素的高度。而可见部分的高度其实就是clientHeight,也就是scrollHeight>=clientHeight恒成立。在有滚动条时讨论scrollHeight才有意义,在没有滚动条时scrollHeight==clientHeight恒成立。单位px,只读元素。


图片描述

scrollTop: 代表在有滚动条时,滚动条向下滚动的距离也就是元素顶部被遮住部分的高度。在没有滚动条时scrollTop==0恒成立。单位px,可读可设置。
offsetTop: 当前元素顶部距离最近父元素顶部的距离,和有没有滚动条没有关系。单位px,只读元素。


图片描述

offsetTop: 当前元素顶部距离最近父元素顶部的距离,和有没有滚动条没有关系。单位px,只读元素。


图片描述

以下内容转载自:
https://blog.csdn.net/shibazijiang/article/details/103894498

我们开发web代码的时候,经常会遇到各种高度的计算. 因为总是忘记几者之间得区别,每次都要现查,这次通过这篇文章彻底搞明白这几个长度的区别.


在这里插入图片描述

1.定义说明

条目 含义 图示
clientHeight 元素的像素高度,包含元素的高度+内边距,不包含水平滚动条,边框和外边距
在这里插入图片描述
offsetHeight 元素的像素高度 包含元素的垂直内边距和边框,水平滚动条的高度,且是一个整数
在这里插入图片描述
scrollHeight 元素内容的高度,包括溢出的不可见内容
在这里插入图片描述
offsetLeft 返回元素左上角相对于offsetParent的左边界的偏移像素值

注意点

1.对块级元素来说,offsetTop、offsetLeft、offsetWidth 及 offsetHeight 描述了元素相对于 offsetParent 的边界框。但是文本框不是如此.文本框的offsetLeft和offsetTop是第一个文本框的左偏移和上偏移.

2.offsetParent元素指改元素的定位元素以及最近的table,td,th,body.
可见,offsetParent和position属性的包含块概念类似.大部分场景下可以通用.

3.offsetTop和offsetLeft都是相对于其内边距边界的.

offsetLeft和left属性的区别

1.position为fixed时值不同
当position为fixed的时候,offsetLeft的值将会是null,而left此时一般有确定的数字值.
2.相对边距不同
offerset的是相对于offsetParent的内边距边界,left是相对于包含块的外边距边界.
3.包含块有区别
offerset相对与定位的祖先元素或者 table/td/th/body等祖先元素,left仅仅是相对于定位祖先元素+body

clientHeight与offsetHeight的区别

clientHeight仅仅包含内边距+高度,offsetHeight包含内边距+滚动条+边框
所以可以这样说: clientHeight+滚动条高度+边框 = offsetHeight

参考资料:

1.offsetHeight官方说明
https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLElement/offsetHeight

2.clientHeight官方说明
https://developer.mozilla.org/zh-CN/docs/Web/API/Element/clientHeight

二、js事件对象Event获取pageX,clientX,screenX,offsetX,layerX的方式与区别

pageX:
鼠标在页面上的位置,从页面左上角开始,即是以页面为参考点,同一个元素坐标不随滑动条移动而变化

clientX:
鼠标在页面上可视区域的位置,即是以浏览器滑动条此刻的滑动到的位置为参考点,同一个元素坐标随滑动条移动而变化.

注:
1、如果元素位于body中,e.clientX + document.body.scrollLeft - document.body.clientLeft = e.pageX,
2、e.clientX包括了body的边框,document.body.scrollLeft也包括了body边框,body表框运算重复,减去document.body.clientLeft,即去掉重复的body边框

screenX:
获取到的是触发点相对显示器屏幕左上角的距离,不随页面滚动或浏览器移动而改变

offsetX:
获取到的是鼠标触发点相对于目标事件元素(被触发DOM)左上角的距离(确切的说是到边框外边界的距离),其中在IE中以内容区左上角为基准点不包括边框,如果触发点在边框上会返回负值,而chrome中以边框左上角为基准点。

layerX:
获取到的是鼠标触发点相对于offsetParent元素左上角的距离(确切的说是到边框外边界的距离),包括中间所有元素的padding、margin、border及元素宽度值之和),其中在IE中以内容区左上角为基准点不包括边框,如果触发点在边框上会返回负值,而chrome中以边框左上角为基准点。

注:关于offsetParent元素
1、如果当前元素的祖先元素没有进行CSS定位(position为absolute或relative),offsetParent为body。
2、如果当前元素的祖先元素(包括当前元素)中有CSS定位(position为absolute或relative),offsetParent取最近的那个祖先元素(包括当前元素)。

总结:
1、使用pageX获取带滚动条的到页面边缘尺寸
2、使用clientX获取到浏览器可是区域的尺寸,没有滚动条,pageX == clientX
3、使用screenX获取到屏幕边缘尺寸
4、使用offsetX获取到当前元素边缘尺寸
5、使用layerX获取到offsetParent边缘尺寸

三、页面元素坐标和偏移(clientX/pageX/screenX/layerX/offsetWidth/scrollWidth/clientWidth等)相关整理

鼠标事件都是在特定位置发生的,我们可以通过event事件对象的各种属性来获得事件发生的坐标位置,有相对于视口的,有相对于整个文档的,同样页面元素的位置也有相对视口的,也有滚动后的,这些都比较容易混淆,所以整理在这里,备忘,待查。

1.客户区坐标位置(clientX/clientY)

我们可以通过event事件对象的clientX/clientY属性获得事件发生时鼠标指针在视口中的水平和垂直坐标。

示意图:

image

2.屏幕坐标位置(screenX/scrennY)

通过event事件对象的screenX/screenY属性,可以获取鼠标事件发生时鼠标光标相对于整个电脑屏幕的坐标信息。

示意图:

image

clientX/clientY和screenX/screenY区别demo:clientX/clientY和screenX/screenY区别demo

demo 源代码戳这里:https://github.com/demo.html

3.页面坐标位置(pageX/pageY)

通过事件对象的pageX/pageY属性可以获得鼠标事件发生时鼠标光标相对于整个文档元素的坐标位置(包含滚动)。

在页面没有滚动的情况下,通常pageX/pageY的值与clientX/clientY的值相等。

4.layerX/layerY

事件对象还有个不那么常见的属性,那就是layerX/layerY,他是对于绝对定位元素来说的,相对于当前点击元素的左上角定位的。当页面上的元素时相对定位(position:relative)的时候,通常pageX/pageY和layerX/layerY的值是相同的,但是当元素绝对定位(position:absolute)了的时候,layerX/layerY就将鼠标光标位置相对于本身的左上角定位了。

下面demo有助于理解,猛戳:

pageX\pageY & layerX\layerY示意demo:pageX\pageY & layerX\layerY

demo代码猛戳这里:https://github.com/pageXandLayerX.html

5.偏移量:(offsetWidth/offsetHeight/offsetLeft/offsetTop)

元素的偏移量(offsetLeft/offsetTop)是相对于它的直接父元素来说的。

   [元素的可见大小由其高度和宽度决定,这包括所有的内边距(padding)、滚动条和边框(border)大小(注意这里面不包括margin喔,因为margin是透明的,一般使用它控制元素之间的间隔)。这是为什么呢,因为吧,可以一试,如果我们给元素添加背景的话,那么背景会被应用 于由内容和内边距组成的区域,而添加边框(border)会在内边距(padding)的区域外边加一条线,margin透明,当然不在可见范围内啦。]

示意图:

image

Tips:

1.如果要想知道某个元素在页面上的偏移量,将这个元素的offsetLeft和offsetTop与其offsetParent的相同属性相加,如此循环至根元素,就可以得到一个基本准确的值。

2.如果有些div他的offsetParent是的话,那么也可以尝试getElementLeft()和getElementTop()方法,不出意外地话会返回跟offsetLeft和offsetTop相同的值。

3.所有这些偏移量都是只读的,而且每次访问的时候都需要重新计算,要注意性能问题。

6.客户区的大小(clientWidth/clientHeight)

  元素的客户区的大小就是指元素内容及其内边距所占空间的大小(滚动条占用的空间不计算在内)。(clientWidth=width+padding(left、right);clientHeight=height+padding(top、bottom))

clientWidth与offsetWidth区别示例:[clientWidth与offsetWidth区别](http://samples.msdn.microsoft.com/workshop/samples/author/dhtml/refs/clientWidth.htm)

7.滚动大小(scrollWidth/scrollHeight/scrollLeft/scrollTop)

 有些元素,即使没有执行任何代码也会自动的添加滚动条,如,但是另外一些元素,则需要通过css的overflow属性进行设置才能滚动。

 通常认为元素是在web浏览器的视口中滚动的元素(ie6之前版本运行在混杂模式下是元素,这也是上面计算视口大小代码if,else的原因),因此带有垂直滚动条的页面总高度就是document.documentElement.scrollHeight。

 ![image](https://upload-images.jianshu.io/upload_images/23628926-e97e6f9b47af590e.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

当overflow属性设置为 auto时,内容可以超过元素的尺寸,并显示滚动条。这时就可以使用scrollwidth属性来检索内容的宽度范围内的元素。

MSDN上找到了相关的例子:scrollWidth属性示例

更具体的信息,可以查看这里:MSDN scrollWidth

Tips:

在确定文档的总高度时,必须取得scrollWidth、clientWidth和scrollHeight、clientHeight中的最大值,这样才能保证在跨浏览器的情况下取得较为准确的结果。

8.window.scrollX/window.scrollY与window.pageXOffset/window.pageYOffset

window.scrollX/window.scrollY返回的是整个文档document在水平和竖直方向滚动了的距离。

window.pageXOffset/window.pageYOffset相当于window.scrollX/window.scrollY的别名一样的。也就是说:
window.pageXOffset == window.scrollX; // 总是返回真

但在跨浏览器的情况下,尽量使用window.pageXOffset/window.pageYOffset比较好。

所以为了保险起见,使用下面这样的代码来判断文档在垂直和水平防线滚动的距离比较好:

var x = (window.pageXOffset !== undefined) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft; var y = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;

9.window.innerHeight/window.innerWidth

window.innerHeight/window.innerWidth记录了视口内文档元素的实际高度和宽度,实际上还有window.outerHeight/window.outerWidth。

下图可以很好地区分两者:

image

另外,如果页面滚动了也不会影响他的innerHeight和innerWidth值:

image
image

此外,如果页面中有frameset时:

var intFrameHeight = window.innerHeight; // or

var intFrameHeight = self.innerHeight;
// will return the height of the frame viewport within the frameset

var intFramesetHeight = parent.innerHeight;
// will return the height of the viewport of the closest frameset

var intOuterFramesetHeight = top.innerHeight;
// will return the height of the viewport of the outermost frameset

10.getBoundingClientRect()方法

   getBoundingClientRect用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置。getBoundingClientRect是DOM元素到浏览器可视范围的距离(不包含文档卷起的部分)。该函数返回一个Object对象,该对象有6个属性:top,lef,right,bottom,width,height;这里的top、left和css中的理解很相似,width、height是元素自身的宽高,但是right,bottom和css中的理解有点不一样。right是指元素右边界距窗口最左边的距离,bottom是指元素下边界距窗口最上面的距离。

  通过这个方法可以比较方便的获取页面元素的位置:
    var X= this.getBoundingClientRect().left+document.documentElement.scrollLeft;
    var Y =this.getBoundingClientRect().top+document.documentElement.scrollTop;

关于这个方法MSDN上有详细的解释:getBoundingClientRect()方法

总结:

上面那些属性都是很容易搞混的。而且也要注意不同的浏览器中可能存在的差别,使用的时候测试一下就能更准确的应用了。

搞清楚了上面这些相关属性和方法,应该就能理解小胡子写给我的这个demo了: js原生拖放

源代码在这里:https://github.com/dragdemo.html

整理这篇文章的契机,就是我在实现原生的拖放功能。

备忘,待查。

你可能感兴趣的:(搞清clientHeight、offsetHeight、scrollHeight、offsetTop、scrollTop)