计算元素的尺寸,可以通过以下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.documentElement
的 clientWidth
和 clientHeight
<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