一文读懂 offset client scroll 如何计算元素尺寸

计算元素的尺寸,可以通过以下offset client scroll getBoundingClientRect 四种方式来获得,本文详细说明下四种api的使用方式。

一 、偏移尺寸

偏移尺寸(offset dimensions),包含元素在屏幕上占用的所有视觉空间。元素在页面上的视觉空间由其高度和宽度决定,包括所有内边距、滚动条和边框(但不包含外边距)。以下4 个属性用于取得元素的偏移尺寸。

  • offsetHeight,返回该元素的像素高度,高度包含该元素的垂直内边距和边框,且是一个整数。
  • offsetWidth,元素在水平方向上占用的像素尺寸,包括它的宽度、垂直滚动条宽度(如果可见)和左、右边框的宽度。
  • offsetLeft,返回当前元素左上角相对于 HTMLElement.offsetParent 节点的左边界偏移的像素值。
  • offsetTop,返回当前元素相对于其 offsetParent 元素的顶部内边距的距离。

offset height/width 返回的是 width/height + padding + [滚动条] +border 的像素值

offset left/top 是相对 offsetParent,下面我们通过例子来说明

<style>
    .wrapper {
        width: 300px;
        height: 300px;
        padding: 10px;
        border: 1px solid #123898;
    }

    .box {
        color: aquamarine;
        width: 100px;
        height: 100px;
        border: 1px solid #123898;
        background-color: #ccc;
    }
</style>
<body>
    <!--
	HTMLElement.offsetParent 是一个只读属性,
	返回一个指向最近的(指包含层级上的最近)包含该元素的定位元素
	或者最近的 table,td,th,body元素
	-->
    <div class="box" id="no-wrapper"></div>
    <div class="wrapper" style=" position: relative;">
        <div class="box" id="with-wrapper"></div>
    </div>
    <div class="wrapper">
        <div class="box" id="with-wrapper-no-position"></div>
    </div>
</body>
<script>
    console.log('#no-wrapper',
        'offsetParent:', noWrapper.offsetParent,
        'offsetWidth:', noWrapper.offsetWidth,
        'offsetHeight:', noWrapper.offsetHeight,
        'offsetLeft:', noWrapper.offsetLeft,
        'offsetTop:', noWrapper.offsetTop)

    console.log('#with-withWrapper',
        'offsetParent:', withWrapper.offsetParent,
        'offsetWidth:', withWrapper.offsetWidth,
        'offsetHeight:', withWrapper.offsetHeight,
        'offsetLeft:', withWrapper.offsetLeft,
        'offsetTop:', withWrapper.offsetTop)

    console.log('#with-wrapper-no-position',
        'offsetParent:', withWrapperNoPosition.offsetParent,
        'offsetWidth:', withWrapperNoPosition.offsetWidth,
        'offsetHeight:', withWrapperNoPosition.offsetHeight,
        'offsetLeft:', withWrapperNoPosition.offsetLeft,
        'offsetTop:', withWrapperNoPosition.offsetTop)
 
// 注意:body 的 padding = 8px,需要加入到 offsetLeft 和 offsetTop 的计算
    
/** #no-wrapper 
    offsetParent: <body>​…​</body>​
    offsetWidth: 102 
    offsetHeight: 102 
    offsetLeft: 8 
    offsetTop: 8
*/
    
/** #with-withWrapper 
	offsetParent: <div class=​"wrapper" style=​" position:​ relative;​">​…​</div>​
	offsetWidth: 102 
	offsetHeight: 102 
	offsetLeft: 10 
	offsetTop: 10
*/ 
/* #with-wrapper-no-position 
	offsetParent <body>​…​</body>​ 
	offsetWidth: 102 
	offsetHeight: 102 
	offsetLeft: 19 
	offsetTop: 443
*/
</script>

二、客户端尺寸

元素的客户端尺寸(client dimensions)包含元素内容及其内边距所占用的空间。客户端尺寸只有两个相关属性:

  • clientWidth:表示元素的内部宽度,属性包括内边距 padding,但不包括边框 border、外边距 margin 和垂直滚动条(如果有的话)
  • clientHeight:这个属性是只读属性,对于没有定义CSS或者内联布局盒子的元素为0,否则,它是元素内部的高度(单位像素),包含内边距,但不包括水平滚动条、边框和外边距

client width/height 返回 width/height + padding - [滚动条]

这两个属性最常用于确定浏览器视口尺寸,即检测 document.documentElementclientWidthclientHeight

<style>
    .box {
        color: aquamarine;
        width: 100px;
        height: 100px;
        padding: 10px;
        border: 1px solid #123898;
        background-color: #ccc;
    }
</style>
<body>
    <div class="box" id="no-scroll"></div>
	<!-- 加文字的目的是为了出现滚动条-->
    <div class="box" id="scroll" style="overflow:auto">clientHeight 属性是一个只读属性,它返回该元素的像素高度,
    高度包含内边距(padding),不包含边框(border),外边距(margin)和滚动条,是一个整数,单位是像素 px。
        clientHeight 可以通过 CSS height + CSS padding - 水平滚动条高度 (如果存在)来计算
    </div>
</body>
<script>
    const noScroll = document.querySelector('#no-scroll');
    const scroll = document.querySelector('#scroll');

    // 注意:chrome/edge/fixfox 浏览器 滚动条 width/height 是17px
    console.log('noScroll',
        'clientWidth',noScroll.clientWidth,
        'clientHeight',noScroll.clientHeight,
    )
    console.log('scroll',
        'clientWidth',scroll.clientWidth,
        'clientHeight',scroll.clientHeight,
    )
    // noScroll clientWidth 120 clientHeight 120
    // scroll clientWidth 103 clientHeight 103
</script>

三、滚动尺寸

滚动尺寸(scroll dimensions),提供了元素内容滚动距离的信息。有些元素,比如 无须任何代码就可以自动滚动,而其他元素则需要使用CSS 的overflow 属性令其滚动。滚动尺寸相关的属性有如下4 个:

  • scrollHeight,没有滚动条出现时,元素内容的总高度。
  • scrollWidth,没有滚动条出现时,元素内容的总宽度。
  • scrollLeft,内容区左侧隐藏的像素数,设置这个属性可以改变元素的滚动位置。
  • scrollTop,内容区顶部隐藏的像素数,设置这个属性可以改变元素的滚动位置。

scrollWidth 和scrollHeight 可以用来确定给定元素内容的实际尺寸。例如,元素是浏览器中滚动视口的元素。因此document.documentElement.scrollHeight 就是整个页面垂直方向的总高度。
scrollWidth 和 scrollHeight 与 clientWidth 和 clientHeight 之间的关系在不需要滚动的文档上是分不清的。如果文档尺寸超过视口寸,则在所有主流浏览器中这两对属性都不相等,scrollWidth 和scollHeight 等于文档内容的宽度,而clientWidth 和clientHeight 等于视口的大小。
scrollLeft 和 scrollTop 属性可以用于确定当前元素滚动的位置,或者用于设置它们的滚动位置。元素在未滚动时,这两个属性都等于0。如果元素在垂直方向上滚动,则scrollTop 会大于0,表示元素顶部不可见区域的高度。如果元素在水平方向上滚动,则scrollLeft 会大于0,表示元素左侧不可见区域的宽度。因为这两个属性也是可写的,所以把它们都设置为0 就可以重置元素的滚动位置。

四、确定元素尺寸

浏览器在每个元素上都暴露了 getBoundingClientRect() 方法,返回一个DOMRect 对象,包含6 个属性:left、top、right、bottom、height 和width。这些属性给出了元素在页面中相对于视口的位置,值可以取小数。

最后通过下面一张图给出所有尺寸的关系:

最外层浅绿色:代表文档的尺寸

虚线内的橘黄色:代表元素的 margin

黄色:代表元素的 padding

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值