JavaScript如何获取dom元素的各种宽度高度?方案对比
发布于 作者:苏南大叔 来源:程序如此灵动~

如果对页面元素的宽度高度做过仔细的调查,就可以发现:这些网页元素的尺寸的宽度width
和高度height
,有着很多的版本。如果较真的话,这些不同取值的宽度高度就显得很混乱。包括:width
/clientWidth
/offsetWidth
/scrollWidth
/innerWidth
/outerWidth
等。这些令人眼花缭乱的宽度之间究竟有什么样的区别和联系呢?

大家好,这里是苏南大叔的程序如此灵动博客,记录苏南大叔和计算机代码的故事。本文探讨使用js
获取页面元素宽度和高度的各种不同属性或方法。测试环境:谷歌浏览器@111.0.5563.111。
测试样本
本文的例子中使用了两个盒子元素作为例子。页面模式是标准模式<!DOCTYPE html>
,盒子模型分别是怪异模式border-box
和正常模式content-box
。

从运行截图上可以看到:
- 盒子模型的默认形态是
content-box
。对比的标准目标尺寸是360*60
。 - 怪异盒子模型(
border-box
)的实际宽度高度是固定不变的,padding
、border
还有滚动条都出现在代码定义的尺寸内部。 - 正常的盒子模型(
content-box
)的实际宽度高度比代码中定义的要大,因为padding
、border
还有滚动条都出现在代码定义的尺寸外部。
本文的测试样本,改编自下面的这两篇文章:
基础尺寸概念
一般来说,获取元素obj
的宽度,大家会使用obj.style.width
来获取。实际上这个值是最错误的值,因为它是必须定义在<dom style='width:300px'>
中才能获取到的,即使能够顺利获取,也大概率和实际的运行值不匹配,这里仅仅是获取定义的值。没通过元素的style
属性定义的话,获取的值为空。
那么实际的运行值和定义值之间的差值来自于padding
、border-width
、margin
以及滚动条。所以,先运算获取padding
、border
、margin
等基础值。
方法 | t1(怪异盒子) | t2(标准盒子) |
---|---|---|
-.style.width | 300px | 空 |
-.style.padding | 空 | 空 |
-.style.border | 空 | 空 |
-.style.margin | 空 | 空 |
getComputedStyle(document.querySelector('#-'), null).width | 360px | 360px |
getComputedStyle(document.querySelector('#-'), null).padding | 15px | 15px |
getComputedStyle(document.querySelector('#-'), null).borderWidth | 5px | 5px |
getComputedStyle(document.querySelector('#-'), null).margin | 10px | 10px |
目前这些width
、padding
、margin
、border
等因素取值完全相同,但是【测试的值和表现出来的效果却完全不同】。getComputedStyle
计算实际值的办法,来自于下面这篇文章:
clientWidth
和clientHeight
方法 | t1(怪异盒子) | t2(标准盒子) |
---|---|---|
-.clientWidth | 333 | 390 |
-.clientHeight | 50 | 90 |
元素可见区域的宽度,包括padding
,不包括滚动条和边框线,不包括margin
。指的是图中的蓝色部分,不包括灰框和滚动条。
offsetWidth
和offsetHeight
方法 | t1(怪异盒子) | t2(标准盒子) |
---|---|---|
-.offsetWidth | 360 | 400 |
-.offsetHeight | 60 | 100 |
offset
= 元素可见区域client
+ 边线和滚动条,不包括margin
。
scrollWidth
和scrollHeight
方法 | t1(怪异盒子) | t2(标准盒子) |
---|---|---|
-.scrollWidth | 333 | 390 |
-.scrollHeight | 90 | 90 |
scroll
包括可见部分client
以及不可见部分。不包括border
,不包括滚动条,不包括margin
,包括因为overflow
被隐藏的部分。
getComputedStyle().width
和jq.width()
方法 | t1(怪异盒子) | t2(标准盒子) |
---|---|---|
-.style.width | 300px | 空 |
-.style.height | 空 | 120px |
getComputedStyle(document.querySelector('#-'), null).width | 360px | 360px |
getComputedStyle(document.querySelector('#-'), null).height | 90px | 90px |
$('#-').width() | 320px | 360px |
$('#-').height() | 20px | 60px |
.style.
这个测量不准,仅仅是定义的值,和实际的值有差距。getComputedStyle
,不同的盒子模型虽然取值一致,但是效果差别很大。怪异盒子的尺寸,包括padding
和border
,是肉眼可见的宽度。标准盒子的尺寸,连padding
都不包括,是个需要想象才能想出来的尺寸,类似css
中inline
的感觉。- 基于
jq
的.width()计算的是最核心(inline
)的尺寸,无论盒子模型是啥,不包括padding
/border
/margin
。


jq.innerWidth()
和jq.outerWidth()
方法 | t1(怪异盒子) | t2(标准盒子) |
---|---|---|
$('#-').innerWidth() | 350 | 390 |
$('#-').outerWidth() | 360 | 400 |
$('#-').innerHeight() | 50 | 90 |
$('#-').outerHeight() | 60 | 100 |
- innerWidth() = width() + padding
- outerWidth() = width() + padding + border
方法 | t1(怪异盒子) | t2(标准盒子) |
---|---|---|
$('#-').innerWidth(true) | [object Object] | [object Object] |
$('#-').outerWidth(true) | 380 | 420 |
$('#-').innerHeight(true) | [object Object] | [object Object] |
$('#-').outerHeight(true) | 80 | 120 |
- innerWidth(true),非预期值,忽略。
- outerWidth(true) = width() + padding + border + margin = outerWidth() + margin
测试代码2
上述一系列结果的得出,使用了下面的测试代码。
代码方案里面,使用了new Function()
的方式,通过字符串定义了函数体。参考文章:
相关文章
- https://newsn.net/say/js-get-computed-style.html
- https://newsn.net/say/css-important.html
- https://newsn.net/say/font-family-computed.html
- https://newsn.net/say/font-family-render.html
总结
更多js
和网页元素的交互文章,请参考链接:


