JS中clientHeight、scrollHeight和offsetHeight的大坑,滚动条抖动问题解决

1.什么是clientHeight、scrollHeight和offsetHeight

学习原生js的人一定会接触到client家族、scroll家族和offset家族。其中clienHeight、scrollHeight和offsetHeight一般用来求网页内容的高度,而对应的clientWidth、scrollWidth和offsetWidth则用来求网页内容的宽度,由于width和Height属性是类似的,所以这里我只挑这三个height来讲一下。

1.1 clientHeight是什么

clientHeight很多文章把它翻译成网页的可见高度,实际上是不太准确的,首先,从单词本身来说,client并没有可见的意思,(client 顾客,客户,委托人)。其次,clientHeight获取到的高度其实和内容可不可见没有一点关系。下面给出我的结论:
clientHeight = (content height) + (padding top+padding bottom);
翻译成中文就是 clientHeight = 内容实际高度 + 上下内边距。
而内容实际高度可以用window.getComputeStyle(obj).height或者$(obj).css(“height”)获取。

简单的来说:在网页的盒子模型中,一个元素由内到外分别由 height + padding + border + margin组成,而clientHeight只取前面的height和padding。不管内容可不可见,即使你用定位把元素移出屏幕外,clientHeight获取到的值仍然不变。
clientHeight的形象说明

1.2 offsetHeight是什么

单词offset意为补偿,抵消,而offsetHeight也很简单,关于offsetHeight网上并没有太多争议,这里直接给出我的结论
offsetHeight = height + padding + border.
即在clientHeight的基础上加上了上下border的高度。
同样的offsetHeight获取到的高度是网页实际渲染出来的高度+内边距+边框。和元素本身是否可见无关。
在这里插入图片描述

1.3 clientHeight和offsetHeight的注意点

  1. 当元素设置为display:none;之后,clientHeight和offsetHeight的高度均变为0,因为浏览器不会对display:none的元素进行渲染,所以使用时一定要注意这一点.
  2. 当父元素没有明确高度时,clientHeight和offsetHeight计算高度时,不会计算设置了绝对定位或者固定定位的元素的宽高,只会对子元素中的标准流元素和清除了浮动的浮动元素高度进行累加得到父元素的实际高度。(这一点有别于我接下来要说的scrollHeight)

1.4 scrollHeight和它的大坑

scrollHeight有的人翻译成可滚动内容的高度,这个翻译还是比较准确的,但是网上大部分人都没有讲清楚scrollHeight到底是什么。这里我给出我的结论。

  1. scrollHeight和元素本身的高度完全无关,是浏览器根据元素padding和子元素的盒模型高度累加计算出来的。
  2. scrollHeight计算高度时,会累加上以自身为定位祖先元素的所有后代定位元素的可视高度。
    什么意思呢,让我们来看一个例子:
    在这里插入图片描述
    可以看到,在用scrollHeight获取可滚动内容的高度时有这么一个坑,那就是当你不希望定位的后代元素被计算入滚动总高度的时候,使用scrollHeight将导致出现比较大的错误。
    这个问题我也是这两天封装一个滚动条组件的时候才遇到的。本来想着用盒子的scrollHeight去获取内容的高度,但是却导致了滚动条的抖动问题,原因是我让定位的后代元素随着滚动高度而改变位置和高度,导致scrollHeight获取到值发生改变,频繁地触发滚动条的刷新,导致抖动。解决办法:
    1.如果是自己封装的滚动条组件,则不要使用scrollHeight获取内容高度,改用非定位子元素的offsetHeight累加来计算得出内容高度;
    2.如果是采用默认的浏览器滚动条如overflow : auto;则想办法让不希望计入滚动高度的元素分离出来,例如用position:fixed代替positon:absolute;或者把它移除结构外。

jQuery和原生js获取高度的方式对比:

设要获取的元素为obj,另外此处的获取方法只针对box-sizing:content-box;对于box-sizing:border-box;暂时没有测试。有兴趣的小伙伴可以自己去试一下。
1.只想获取内容实际高度的(只有height ,不包括padding、border、margin)
原生js: window.getComputeStyle(obj).height----------- jQuery: $ (obj).css(“height”)或$(obj).height();
2.只想获取height+padding.
原生js: obj.clientHeight---------- jQuery: $ (obj).innerHeight();
3.只想获取height+padding+border
原生js: obj.offsetHeight--------------- jQuery: $ (obj).outerHeight();
4.想获取height+padding +border +margin
原生js: 暂无-------------jQuery: $ (obj).outerHeight(true);

好了,今天我就写这么多吧,这是我的第一篇博客,作者郑伟斌,写于2019/4/9,转载请注明出处,谢谢大家。

  • 31
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
### 回答1: `clientHeight` 和 `offsetHeight` 是 JavaScript 的两个元素尺寸属性。 `clientHeight` 表示元素的内容高度,不包括边框、滚动条等。 `offsetHeight` 表示元素的高度,包括内容高度、边框高度、滚动条高度等。 ### 回答2: clientHeightoffsetHeight都是DOM经常使用的属性,用于计算元素的高度。在某些情况下,它们的结果可能不相同,这主要取决于页面布局和元素样式。 clientHeight是一个只读属性,它用于计算元素的可见高度,即元素内容的可视区域高度,包含在CSS的padding和borderclientHeight不包括滚动条和元素内容的边距,因此它的计算结果可能小于offsetHeight属性。 例如,如果一个div元素有10像素的padding和1像素的边框,它的clientHeight属性将仅包括显示区域的高度,而不包括边距,padding和边框的高度。因此,clientHeight仅仅代表元素的内容高度的一部分大小。 另一方面,offsetHeight属性是用于计算元素在页面上占用的整体高度,包含CSS的padding、border和元素的高度。这意味着offsetHeight包括了所有的高度,从元素的边界到其内部内容的底部边界,且不含滚动条。 以同样的例子,如果一个div元素有10像素的padding和1像素的边框,它的offsetHeight将包括整个元素的高度,包括padding和边框高度。因此,offsetHeight代表了元素在页面上占用的总高度大小。 总的来说,在计算元素的高度时,我们需要仔细区分clientHeightoffsetHeight属性之间的差异,选择合适的属性来计算所需的元素高度。 然而使用时也要考虑到浏览器的兼容性问题,因为有些浏览器计算方式不同,结果也不尽相同。 ### 回答3: clientHeightoffsetHeight是Web开发常用的两个属性。这两个属性都可以用来获取元素的高度,但它们之间有所不同。 clientHeight是指元素内容以及内边距的高度。这个属性只包括元素的内容高度(不包括边框和外边距)。它的值是一个数值,以像素为单位,可以通过JavaScript来获取。例如,如果一个元素的内容高度是300像素,这个属性的值就是300。 offsetHeight是指元素的高度,包含元素的内容、内边距、边框和外边距。这个属性的值是一个数值,以像素为单位,也可以通过JavaScript来获取。例如,如果一个元素的内容高度是300像素,内边距是20像素,边框是2像素,外边距是10像素,这个属性的值就是332。 可以通过以下代码来获取元素的clientHeightoffsetHeight: var element = document.getElementById("myElement"); var clientHeight = element.clientHeight; var offsetHeight = element.offsetHeight; 需要注意的是,clientHeightoffsetHeight都可以受到CSS样式的影响。例如,如果元素的display属性设置为none,这两个属性的值都是0。因此,在使用这两个属性的值时,需要注意元素是否已经被渲染。另外,如果元素有滚动条clientHeightoffsetHeight的值还会包括滚动条的高度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月桦剑士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值