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

深入理解高度。获取屏幕、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

要回复文章请先登录注册

夜乐科技

夜乐科技

如何可以获取IPHONE的真实分辨率?我在ip6能正常,ip7p就不正确。

const sysInfo = uni.getSystemInfoSync()
const w = sysInfo.screenWidth;
const h = sysInfo.screenHeight;
console.log(`mode > ${sysInfo.model} , info size > W:${w} H:${h}`)

const screenW = plus.screen.width;
const screenH = plus.screen.height;
console.log(`screen size > W: ${screenW} H:${screenH}`);

const resolutionW = plus.screen.resolutionWidth;
const resolutionH = plus.screen.resolutionHeight;
console.log(`resolution size > W:${resolutionW} H:${resolutionH}`)

mode > iPhone7 Plus , info size > W:414 H:736
screen size > W: 1242 H:2208
resolution size > W:414 H:736
2020-10-23 16:24
4***@qq.com

4***@qq.com

请问横屏手机如何获取键盘高度
2019-07-30 19:40
8***@qq.com

8***@qq.com

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

8***@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
z***@163.com

z***@163.com

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

3***@qq.com

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

gadget2k

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