DCloud_heavensoft
DCloud_heavensoft
  • 发布:2015-05-03 04:57
  • 更新:2019-01-26 22:27
  • 阅读:65368

深入理解高度。获取屏幕、webview、软键盘高度

分类:HTML5+

如果没有手动调整过webview的高度的话,默认情况下,屏幕的高度=顶部状态栏的高度+webview的高度。
如果软键盘打开,则屏幕的高度=顶部状态栏的高度+webview的高度+软键盘的高度。
HTML5 规范目前没有提供状态栏高度和软键盘高度的直接的查询方法,不过有了Native.js,我们还是能查询到所有这些高度的数值。

背景知识介绍:

手机屏幕有真实的物理分辨率,比如小米note的高度是1920px。  
但在网页里,一个10px的字体,并不会小的看不清,因为webview提供了逻辑分辨率的概念。  
如果不在meta里设置,默认下小米note的放大系数scale是3,就是会放大3倍显示。  
也就是对于HTML而言,小米note的高度是1920/3=640px。  
如果网页是全屏的,没有顶部状态栏,那么一个640px高的div将撑满屏幕高度。  

获取屏幕、顶部状态栏和软键盘的高度

1. 屏幕的高度

获取屏幕的高度很简单,HTML自带了screen.height,直接就可以得到屏幕的整体高度,单位是px,物理分辨率值(不是HTML的逻辑分辨率)。  
HTML5Plus里提供了plus.screen.resolutionHeight方法,也是屏幕高度,但这个值是逻辑分辨率的高度。参考[http://html5plus.org/doc/zh_cn/device.html#plus.screen](http://html5plus.org/doc/zh_cn/device.html#plus.screen)  
screen.height = plus.screen.resolutionHeight*plus.screen.scale  

2. 获取webview高度

虽然webview的getStyle可以得到webview的高度,但开发者如果不手动设置的话,默认值是100%,这个值对本文探讨的问题没有意义。我们需要px的物理高度。  
在Android里通过如下js代码可以得到webview的高度:plus.android.invoke(plus.android.currentWebview(),"getHeight")   
这是一段Native.js代码,由于Android的webview原生对象就有getHeight()方法,所以就可以直接这样调用。  
当然webview原生对象还有很多方法属性都可以调,具体参阅[Native.js入门](http://ask.dcloud.net.cn/docs/#http://ask.dcloud.net.cn/article/88)  
图1(此图中,物理分辨率是蓝色字体,逻辑分辨率是黑色字体) 对于iOS,就没必要使用Native.js这么复杂的技术了,iOS的屏幕高度是固定的几个,直接判断屏幕高度和设备型号就可以了。

3. 获取状态栏高度

顶部状态栏比较复杂,如果webview设了全屏,那么状态栏高度就为0。  
如果设置了沉浸式状态栏,状态栏透明了,虽然状态栏存在理论高度,但webview高度是全屏的。  
plus.navigator.getStatusbarHeight(),这个api专门获取状态栏高度。  

4. 获取输入法高度

当弹出输入法时,在Android上,webview的高度会自动减少,留出空间给软键盘。  
那么输入法高度=屏幕高度-状态栏高度-webview高度  
在小米note上,默认输入法高度是 863px。  
图2(此图中,物理分辨率是蓝色字体,逻辑分辨率是黑色字体)

5. 流应用任务栏高度

在流应用环境中,比如iOS流应用,会有一个流应用任务栏,这个任务栏的出现会挤压webview的高度。  
如果开发者要设置一个元素居底,请使用bottom方法,而不是通过屏幕高度-webview高度设top,以避免出现流应用任务栏时高度错位。  

说说HTML里的几个高度

其实HTML自己也提供了很多高度相关的api,除了screen.height还有document.body.clientHeight,document.body.scrollHeight,感觉也很容易混淆。  
document.body.clientHeight是网页内容区的有效高度,符合盒模型。document.body.scrollHeight是网页可滚动区域的高度。  
如图2所示:  
- 此时document.body.clientHeight小于webview高度,而document.body.scrollHeight等于webview高度,即document.body.scrollHeight=plus.android.invoke(plus.android.currentWebview(),"getHeight") 。  
- 如果数字不是1-5,而是1-10,那么document.body.clientHeight会继续增加,但内容不够多,不会滚动,document.body.scrollHeight不变,仍是webview高度。  
- 如果网页内容非常多,数字到了40,那document.body.clientHeight会继续增加,并且只要发生了滚动,则document.body.clientHeight=document.body.scrollHeight  

其他相关知识。

  • 监控软键盘是否弹出,Android上可以使用HTML自带的resize事件。
    但是要判断横竖屏,因为横竖屏切换也会造成resize,所以高度变而宽度不变,就是软键盘弹出或消失了。
  • 强制弹出键盘,也有Native.js示例,http://ask.dcloud.net.cn/question/2324
  • hello uni-app和hello mui都有聊天示例模板,有底部输入框跟随键盘顶起的示例,可以参考下。
22 关注 分享
YanRong zhoushp_cn 蔡繁荣 木记 guyskk scarecrow safaring JL 沙师兄 冬瓜鸡汤 512973585@qq.com DCloud_UNI_Trust 丿白开水 雪之梦技术驿站 gaohuazi 576164240@qq.com 小明子 mlm8368 梓蜀微术 dev7 小U的主人 bashi1@126.com

要回复文章请先登录注册

8112857@qq.com

8112857@qq.com

回复 DCloud_heavensoft: iPhone设备很多,而且iphone上边又有很多第三方输入法,而且输入法类型又有很多(文字、数字等),这些不同的类型都造成iphone的高度不一样,那么请问iphone的输入法高度怎么获取啊
2019-01-26 22:27
8112857@qq.com

8112857@qq.com

IOS的,怎么拿到键盘的高度啊?而且IOS还有很多第三方的输入法,每个输入法的高度都不一样
2019-01-26 22:25
漠

回复 漠: 好吧,还是会减少的,只是iPhone5s不会减少
2017-12-27 10:09
漠

回复 蔡邵鑫: 这个文章是在两年前发布的,很多属性都已经更改了,状态栏高度可以直接获取,就是在ios中,软键盘出现后,webview的高度并不会随之减少了
2017-12-26 20:51
蔡邵鑫

蔡邵鑫

var screenHeight = plus.screen.resolutionHeight;//获取屏幕高度
或者 var screenHeight = screen.height;

var webviewHeight = plus.android.invoke(plus.android.currentWebview(),"getHeight");//获取webview的高度

我用方法获取的屏幕高度小于获取webview的高度 减出来的都是负数了......

是否可以比较两次webview的高度变化作为软键盘的高度?
2017-12-05 16:59
zhuhong02199@163.com

zhuhong02199@163.com

我想获取的是在屏幕整个窗口上显示的内容的高度,不是屏幕的高度,怎么获取????
2017-04-26 11:24
308106363@qq.com

308106363@qq.com

回复 DCloud_heavensoft: 那只要苹果一出新品,高宽变了,程序就跟着升级?
2017-03-20 18:09
gadget2k

gadget2k

回复 DCloud_heavensoft: 我刚试过,软键盘弹出会触发resize, 收回却不会触发resize, 为什么?似乎高度变短了就不再变回来。我在键盘消失后再次查询window.innerheight, 只有220左右。
2017-02-17 22:14
gmmx133

gmmx133

逻辑分辨率 能设置否
2017-02-12 16:53
1602725012@qq.com

1602725012@qq.com

mark
2016-10-20 14:20
hjdddd

hjdddd

回复 DCloud_heavensoft: 我的页面弹出软键盘好像不会触发resize事件呢?这个是什么情况呢?
2016-04-05 10:03
DCloud_heavensoft

DCloud_heavensoft (作者)

回复 追逐者: 看你调多少了,只要软键盘弹出会挤压webview的高度变化,就会触发resize
2016-03-31 19:29
追逐者

追逐者

那么如果手动调整过webview的大小呢?监听resize还可以判断软键盘弹出吗?
2016-03-31 14:23
safaring

safaring

可以使用如下获取弹出软键盘后,屏幕可视区域的高度:

document.body.clientHeight / plus.screen.scale
2015-09-18 16:00
Mr丶Song

Mr丶Song

回复 twolun: 55555555555555555
2015-08-10 16:07
twolun

twolun

回复 DCloud_heavensoft: 谢谢,感谢晚了,哈哈
2015-08-03 11:34
小D额

小D额

回复 DCloud_heavensoft: 在ios上面,网页的键盘会多出一行类似于工具栏的东西,怎么样去掉这一行工具栏呢?这样会让APP看起来想个网页
2015-07-31 16:04
Liosixer

Liosixer

回复 DCloud_heavensoft: 这也可以。。。。 好的, 我知道它就是20px
2015-07-06 15:05
DCloud_heavensoft

DCloud_heavensoft (作者)

回复 Liosixer: iphone的设备高宽都是固定的几个值,判断device的高度就都知道了。
2015-07-03 21:45
DCloud_heavensoft

DCloud_heavensoft (作者)

回复 twolun: 是要这个吗?http://www.html5plus.org/doc/zh_cn/device.html#plus.screen
2015-07-03 21:40
Liosixer

Liosixer

为什么没有iphone的手机屏幕高度获取?
2015-07-03 18:21
twolun

twolun

没有找到screen的api?????????????
2015-07-01 08:20