我们在写js的时候经常碰到获得屏幕宽度,屏幕高度的问题,经常容易搞混淆,那么今天我们今天来探究下。
常用的几个js属性
window.outerWidth / outerHeight
window.innerWidth / innerHeight
screen.availWidth / availHeight
document.documentElement.clientWidth / clientHeight
-
document.documentElement.offsetWidth / offsetHeight
(待续) -
document.documentElement.scrollWidth / scrollHeight
(待续)
以上几个属性便是我们经常用来获取屏幕尺寸相关的属性了,稍稍不慎就很容易用错,接下来我们以chrome
浏览器来测试下这几个属性。
搞清楚这几个问题之前,我们要先搞清楚几个概念:
1.屏幕 - 我们的电脑或者手机显示屏
2.窗口 - window, 浏览器的窗口,这其中还包含工具栏
3.视口 - viewport,网页显示区域
4.网页 - html,网页区域
按大小包含范围排序的话: 屏幕
> 窗口
> 视口
。网页大小可以比他们大可以比他们小,大了就显示滚动条。
屏幕我们好理解,但是窗口和视口,网页有什么区别呢? 说点通俗的
你打开一个网页还开了F12的手机模式调试网页,你的窗口区域就是你的浏览器的在屏幕上显示的大小了,这包含浏览器的标签页,搜索栏,工具栏甚至是调试工具在里面,而视口是哪里呢,视口就是你调试的手机网页那小块区域了,视口里面要显示的是网页的,网页可大可小, 比如太大了就出现滚动条了。
浏览器里面提供了这四个类型大小相关的属性,分别是
- screen.availWidth 和 screen.availHeight
- window.outerWidth 和 window.outerHeight
- window.innerWidth 和 window.innerHeight
- document.documentElement.clientWidth 和 document.documentElement.clientHeight
1.screen.availWidth / availHeight
这一组是跟屏幕有关的, 跟网页没有关系,基本上在设备上是固定不变的,常用的是:
screen.availWidth // 显示屏幕可用宽度 (不包括Windows任务栏)
screen.availHeight // 显示屏幕可用高度(不包括Windows任务栏)
screen.width // 屏幕宽度,整块屏幕
screen.heigh t// 屏幕高度,整块屏幕
screen.colorDepth // 回目标设备或缓冲器上的调色板的比特深度
screen.pixelDepth// 返回屏幕的颜色分辨率(每象素的位数)
2.window.outerWidth / outerHeight
关于window.outerWIdth
的定义 MDN上有一段说明, 关于window.outerHeight
的定义也是类似:
概述
Window.outerWidth 获取浏览器窗口外部的宽度。表示整个浏览器窗口的宽度,包括侧边栏(如果存在)、窗口镶边(window chrome)和调正窗口大小的边框(window resizing borders/handles)。
随便打开一个窗口打印下这两个数据, 然后量尺寸:
可以看到window.outerWidth
和 window.outerHeight
是 977 * 777
, 而我们截图出来的图也是 977 * 777
,
而且图还带有透明的边。可以看出MDN上说的这两个属性是要包含窗口镶边
的,这个win32窗口决定的。至于为什么会这样,可以参考 知乎
3.window.innerWidth / innerHeight
关于window.innerWidth
的定义 MDN - window.innerWidth 上也有一段说明, 关于window.innerHeight
的定义也是类似:
概述
浏览器视口(viewport)宽度(单位:像素),如果存在垂直滚动条则包括它。
我们可以在Chrome上按F12
,让弹出来的开发者工具挤占显示区域:
可以看出 window.innerWidth
明显 小于 window.outerWidth
, window.innerWidth
也正好是显示区域的宽度。
4.document.documentElement.clientWidth / clientHeight
获取文档区域的宽度/宽度(他的显示区域是受视口限制的),不包括滚动条。document.documentElement
是文档里的html元素,clientWidth 和 clientHeight 对应的也是他的宽和高。
所以:
1 screen.availWidth
和 screen.availHeight
是屏幕(screen)的大小。
-
window.outerWidth
和window.outerHeight
是浏览器的窗口(window)大小(包括滚动条)。 -
window.innerWidth
和window.innerHeight
是浏览器的视口(viewport)大小(包括滚动条),就是浏览器窗口内显示网页的区域大小。 - 一般来说PC的网页
window.innerWidth
要比window.outerWidth
小。开发时一般都用window.innerWidth
和window.innerHeight
, 这个跟视口大小是挂钩的。
<meta name="viewport">标签对上述属性的影响
PC上这个属性可以忽略,主要讨论的是移动端浏览器的影响。
在移动端显示网页我们一般是加上:
<meta name=viewport content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
意思就是:
设置视口宽度等于设备宽度,禁止缩放,伸缩比例1:1
有如下属性:
- width: 定义视口的宽度,单位为像素,取值有 ‘device-width’ 或者 正整数, 默认是980。
- height: 定义视口的高度,这个属性对我们并不重要,很少使用, 默认是1560。
- initial-scale: 设置页面的初始缩放值,为一个数字,可以带小数
- minimum-scale :允许用户的最小缩放值,为一个数字,可以带小数
- maximum-scale :允许用户的最大缩放值,为一个数字,可以带小数
- user-scalable: 是否允许用户进行缩放,值为"no"或"yes", no 代表不允许,yes代表允许。默认是yes。
注意: 如果width和height中只定义了一个, 未定义的width和height的,是按照 width / height = window.outerWidth / window.outerHeight 这个比例算出来的。
也就是说:
如果我我们不加上上面那段meta标签,在手机上显示网页,我们得到的网页是这样的(手机像素为1920* 1080的微信浏览器):
- window.innerWidth = 980
- window.innerHeight = 1560
- window.outerWidth= 360
- window.outerHeight = 573
- document.documentElement.clientWidth= 980
- document.documentElement.clientHeight= 1559
- 可以缩放和滚动
可见只有window.outerWidth , window.outerHeight是不受这个标签的影响的。
我们加上之后:
- window.innerWidth = 360
- window.innerHeight = 573
- window.outerWidth= 360
- window.outerHeight = 573
- document.documentElement.clientWidth= 360
- document.documentElement.clientHeight= 573
如果我们把 width
属性改成 700,其他不变
- window.innerWidth = 360
- window.innerHeight = 573
- window.outerWidth= 360
- window.outerHeight = 573
- document.documentElement.clientWidth= 700
(*发生变化)
- document.documentElement.clientHeight= 1114
(*发生变化)
可以看出只有 document.documentElement.clientWidth / clientHeight
发生了变化, 其他属性未发生变化
所以: width属性修改的是 document.documentElement.clientWidth
的值
如果我们把 initial-scale
和 maximum-scale
属性都改成 2, 其他不变
- window.innerWidth = 180
(*发生变化)
- window.innerHeight = 287
(*发生变化)
- window.outerWidth= 360
- window.outerHeight = 573
- document.documentElement.clientWidth= 360
- document.documentElement.clientHeight= 573
- 不可以缩放,可以滚动
可以看出只有 window.innerWidth / innerHeight
发生了变化
initial-scale
和 minimum-scale
,maximum-scale
属性修改的是 innerWidth
和 innerHeight
的值,
而且 innerWidth = outerWidth / 放大比例
得出结论:
- 修改viewport属性的width部分,影响的是
document.documentElement.clientWidth
,
具体为:
document.documentElement.clientWidth = Math.max(width, window.innerWidth) // 两者取最大的 -
initial-scale
和minimum-scale
,maximum-scale
影响的是innerWidth
和innerHeight
具体为:
window.innerWidth = window.outerWidth / 计算出的缩放比例
window.innerHeight = window.outerHeight/ 计算出的缩放比例
3.一般我们不会设置‘height’的属性,这样的话,网页clientWidth和clientHeight的比例等于
window.outerWidth / window.outerHeight的比例
回到开头,一般我们开发手机网页,会加上
<meta name=viewport content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
最后的结果是:
window.innerWidth, window.outerWidth, document.documentElement.clientHeight 三者相同, 高度也是一样,在手机端获取屏幕高度,就都可以用了,因为都是一样大小(前提是你不要主动给html加宽高的样式)