DCloud_heavensoft
DCloud_heavensoft
  • 发布:2015-05-03 04:57
  • 更新:2020-10-23 16:24
  • 阅读:96631

深入理解高度。获取屏幕、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都有聊天示例模板,有底部输入框跟随键盘顶起的示例,可以参考下。
25 关注 分享
YanRong zhoushp_cn 蔡繁荣 木记 guyskk scarecrow safaring JL 沙师兄 冬瓜鸡汤 5***@qq.com Trust 丿白开水 雪之梦技术驿站 gaohuazi 5***@qq.com 小明子 mlm8368 梓蜀微术 dev7 湖东呀 b***@126.com Fancye 风雨天涯 p***@163.com

要回复文章请先登录注册

gmmx133

gmmx133

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

1***@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

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

evcardxx

回复 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