【发布时间】:2011-05-05 15:02:32
【问题描述】:
在 javascript dom 中 - 元素的 offsetHeight 和 clientHeight 有什么区别?
【问题讨论】:
-
这是一个很好的演示示例jsfiddle.net/shibualexis/yVhgM/3
标签: javascript
在 javascript dom 中 - 元素的 offsetHeight 和 clientHeight 有什么区别?
【问题讨论】:
标签: javascript
返回对象可见区域的高度,以像素为单位。该值包含有内边距的高度,但不包括滚动条、边框和边距。
返回对象可见区域的高度,以像素为单位。该值包含内边距、滚动条和边框的高度,但不包括边距。
所以,offsetHeight 包括滚动条和边框,clientHeight 没有。
【讨论】:
clientSize(毕竟它是视口),但需要在重排整个文档后计算offsetHeight?
Oded 的答案是理论。但理论和现实并不总是相同的,至少对于
或 元素而言,它们可能对 javascript 中的滚动操作很重要。微软在MSDN中有一张不错的图片:
如果您有一个显示垂直滚动条的 HTML 页面,您会期望
或 元素的 ScrollHeight 生成器大于 OffsetHeight,如图所示。这适用于所有旧版本的 Internet Explorer。但这不适用于 Internet Explorer 11,不适用于 Firefox 36。 至少在这些浏览器中 OffsetHeight 与 ScrollHeight 几乎相同,这是错误的。
虽然 OffsetHeight 可能是错误的,但 ClientHeight 始终是正确的。
在不同的浏览器上试试下面的代码,你会看到:
<!DOCTYPE html>
<html>
<body>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<script>
document.write("Body off: " + document.body.offsetHeight
+ "<br>Body cli: " + document.body.clientHeight
+ "<br>Html off: " + document.body.parentElement.offsetHeight
+ "<br>Html cli: " + document.body.parentElement.clientHeight);
</script>
</body>
</html>
虽然旧版 Internet Explorer 显示正确:
Body off: 1197
Body cli: 1197
Html off: 878
Html cli: 874
Firefox 和 Internet Explorer 11 的输出是:
Body off: 1260
Body cli: 1260
Html off: 1276 // this is completely wrong
Html cli: 889
这清楚地表明 offsetHeight 在这里是错误的。 OffsetHeight 和 ClientHeight 应该仅相差几个像素或相同。
请注意,对于不可见的元素,ClientHeight 和 OffsetHeight 也可能有很大不同,例如
【讨论】:
从内到外,一个元素的布局顺序是:[(内容→内边距)→滚动条→边框]→边距。
(..) area 指的是client 的区域,而[..] area 指的是offset。
Margin 被认为是在元素之外,并且从不涉及任何 JS 布局 API。
获取元素布局的 JS API 的详尽列表是:
对于Element类(包括HTML元素和svg元素):
getClientRects()
getBoundingClientRect().{left,top,right,bottom,<strike>x,y,width,height</strike>}
client{Height,Width,Left,Top}
scroll{Height,Width,Left,Top,<strike>LeftMax</strike>,<strike>TopMax</strike>}
对于HTMLElement 类(不包括svg 元素):offset{Height,Width,Left,Top}。
对于window 对象:scroll{X,Y}、page{X,Y}Offset、inner{Height,Width}、outer{Height,Width}、screen{Left,X,Top,Y}。
对于screen 对象:avail{Top,Left,Height,Width}、height、width、<strike>left</strike>、<strike>top</strike>。
因为根元素无法获得滚动条(浏览器滚动条停留在根元素的边框之外)。见codepen。
根据规范,当元素为根元素时,client{Height,Width} 和 scroll{Left,Top} 有特殊定义。
client* 等忽略转换并将值舍入为整数,而getClientRects()/getClientBoundingRect() 涉及转换并返回浮点值。
还有很多其他方面不适合这个答案,所以我总结了一下,发了一篇博文here。
【讨论】:
clientHeight = 元素的高度 + 垂直内边距。
offsetHeight = 元素的高度 + 垂直内边距 + 上下边框 + 水平滚动条(如果可用)。
添加另一个:
scrollHeight = 元素内容的高度(包括屏幕上不可见的内容)+ 垂直填充。
【讨论】: