开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情
一、写在前面
浏览器关于获取宽高的方法实在是太多了,而且每一种获取宽高方法都有它的独特含义,开发的时候需要获取浏览器宽高时,如果不清楚其中的差别,直接从网上抄下来,很有可能达不到自己的目的。
所以我花时间去认真的学习和研究了各种宽高获取方法的差异,并且通过图示来让大家更好的理解它们的含义。
另外,我写了一个网页,里面展示了下面提到的所有方法获取到的值,可以作为一种观察和理解的工具:点我传送
二、方法的分类
获取屏幕宽高的方法可以分为两类:
- 通过 document.body 元素获取宽高;
- 通过 window 对象提供的属性来获取宽高。
两者很重要的 区别 是:document.body属于文档流中的元素,得到的宽高一定是无法脱离文档流限制区域的,是会受页面内容影响;
而通过window对象,如 window.screen 属性获取的宽高,和文档内容无关,不关你渲染什么内容都无法影响这个值。
二、快捷参考表格
元素
方法 | 含义 |
---|---|
document.body.clientWidth/clientHeight | 元素真实宽高 + padding,不包含border、margin等 |
document.body.offsetWidth/offsetHeight | 元素真实宽高 + padding + margin + border + 滚动条 |
document.body.scrollWidth/scrollHeight | 元素内部滚动内容的宽高,注意是元素 内部的滚动 |
document.documentElement.scrollTop/scrollLeft | 流布局下,浏览器滚动内容(滚动条)距离顶部/左侧的位置 |
window对象
方法 | 含义 |
---|---|
window.screen.width/height | 屏幕宽高,包含任务栏等系统占用屏幕的空间大小 |
window.screen.availWidth/availHeight | 屏幕宽高,不 包含任务栏等系统占用屏幕的空间大小 |
window.innerWidth/innerHeight | 浏览器宽高,包含滚动条大小,不 包含浏览器标签栏、收藏夹、控制台等控件大小 |
window.screen.outerWidth/outerHeight | 浏览器宽高,包含浏览器标签栏、收藏夹、控制台等控件大小 |
三、结合图列展开说说
1、document.body.clientWidth 和 document.bodyclientHeight
clientWidth/clientHeight 指元素的不包含边框(border)、外边距(margin)和滚动条(如果存在滚动条),但包含内边距(padding)的宽高。
clientWidth不仅可以作用在body上,它使用于任何页面元素,但 内联元素 该属性为0:
<span id="app">内容</span>
document.getElementById('app').clientWidth // 0
// 即使span存在内容撑起的宽高,但因为时内联元素,所以无法获取clientWidth
2、document.body.offsetWidth 和 document.body.offsetHeight
和clientWidth/clientHeight类似,也是获取元素的宽高,但offsetWidth/offsetHeight包含元素的内外边距、边框和滚动条宽高,也就是整个盒模型的宽高。
还有一点和clientWidth不同,获取的宽高是布局占位的宽高,内联元素同样可以获取到数值。
<span id="app">内容</span>
document.getElementById('app').offsetWidth // 21
// 能够正确获取内联元素的宽度
3、document.body.scrollWidth 和 document.body.scrollHeight
scrollWidth/scrollHeight 是指元素内部滚动内容的宽高。
也就意味着元素的宽高应该是固定的(或者有最大值),并且 overflow 属性不是hidden,保证元素内部内容超出元素大小后,可以出现滚动条,如果元素没有滚动条,则scrollWidth的值和clientWidth的值相等。
注意:一般页面没有调整样式,页面内容堆叠超出浏览器高度,出现滚动条时,实际上是 html根节点 出现的滚动条,而不是body的,body是被撑开的,所以获取document.body.scrollHeight时依然和clientHeight数值一致。
说到滚动内容的宽高了,那就顺便提及一下元素滚动的距离:scrollTop和scrollLeft。
两者表示元素内部滚动后,滚动条(滚动内容)距离元素顶部和左侧的距离,
需要注意的是:上面说到页面堆叠溢出浏览器高度时,body是被撑开的,真实的滚动元素应该是html,因此想要获取到正确的浏览器滚动距离,应该要使用 document.documentElement.scrollTop
,而不是 document.body.scrollTop
,document.documentElement指代的是<html>
元素。
在查找相关资料的时候,很多关于 document.documentElement.scrollTop
和 document.body.scrollTop
的文章,大多数提到chrome只认document.body.scrollTop
,以及移动浏览器和PC浏览器对两者的兼容,不过在今天我测试看来,无论是chrome还是移动PC浏览器,对于标准 document.documentElement.scrollTop
都是认可的了。
如果对于 document.documentElement的使用仍有疑虑,可以使用 document.scrollingElement 进行页面滚动宽高的获取和设置。
4、window.screen.width 和 window.screen.height
window.screen中的width和height,是指浏览器所处屏幕的大小,和浏览器窗口大小以及文档大小无关,无论浏览器是最大化显示还是小窗口显示,都不会影响屏幕的大小。
值得注意的是:这个宽高值是 设备屏幕 的宽高, 不等于 浏览器的宽高。也不等于浏览器可用的宽高。
如果你想观察这个数值的变化,可以通过切换电脑的分辨率来观察。
5、window.screen.availWidth 和 window.screen.availHeight
window.screen的availWidth和availHeight,是指浏览器所处屏幕中,浏览器最大化时可以占用的宽高,这里和window.screen的widht、height的区别在于:availWidth不包含任务栏等系统占用的宽高。
想要观察 window.screen.availWidth 的变化,可以通过设置window的任务栏位置(靠左或靠下),进行观察。
6、window.innerWidth 和 window.innerHeight
innerWidth/innerHeight,是指浏览器窗口内部的宽高,包含滚动条大小,不包含浏览器标签栏、收藏夹栏、侧边栏等浏览器控件占用的大小。
7、window.outerWidth 和 window.outerHeight
window的outerWidth和outerHeight,是指浏览器窗口的宽高,包含滚动条大小、浏览器标签栏、收藏夹栏、侧边栏等浏览器控件占用的大小。
如果你打开浏览器右侧控制台,那 window.innerWidth 是不包含控制台的宽高的,因为控制台属于浏览器控件,但是window.outerWidth是不会受影响的,只有当浏览器大小发生改变时,比如最大化和向下还原时,window.outerWidth才会变化。
参考文档
scrollingElement - Web API 接口参考 | MDN (mozilla.org)
HTMLElement.offsetWidth - Web API 接口参考 | MDN (mozilla.org)
Element.clientWidth - Web API 接口参考 | MDN (mozilla.org)
Element.scrollHeight - Web API 接口参考 | MDN (mozilla.org)
document.documentElement - Web API 接口参考 | MDN (mozilla.org)
Window.innerHeight - Web APIs | MDN (mozilla.org)