发现问题
最近在工作项目中发现,html表单元素获得焦点时,移动端 Android 系统下自动弹出的软键盘会遮挡住表单元素。
这直接导致当页面高度在一屏以内,或表单元素无法通过滚动页面而移动时,用户无法在输入过程中看到元素本身内容。
这个问题在 IOS 下由于其自身的软键盘bug问题,反而不受影响。但很明显,这样的交互效果对于 Android 用户是很差的。
解决思路
发现这个问题后,我先尝试上网查询了一下大家遇到此类问题的解决办法,发现如果是原生app开发时可以通过设置 <activity>
标签定位属性来控制。但是对于 html 来讲,通过 js 控制软键盘比较困难。
继续查找后发现下面这篇帖子:
因为 window.innerHeight
可以获得不计算软键盘在内的窗口高度,受其启发我尝试了更换思路。通过对比“元素的纵坐标(相对于窗口)”与“窗口高度(不计软键盘)”的大小,来控制元素的定位。
最终得到了较为满意的效果。
需要注意的是:
因为软键盘弹出是动画效果,所以需要设置
setTimeout
延迟获取window.innerHeight
。JS获取
offsetTop
属性是相对于父元素定位的,通常需要获取位置的元素都不是在最外层,而遍历上级元素的offset相关属性将导致影响脚本效率。这里使用浏览器接口getBoundingClientRect
更加高效。-
getBoundingClientRect
浏览器兼容性:Chrome Firefox Internet Explorer Opera Safari 1.0 3.0 (1.9) 4.0 (Yes) 4.0 语法:
obj.getBoundingClientRect().top
;IE 中只能获得
left
、top
、botton
、right
的属性值,而现代浏览器还能获取到元素的width
和height
;bottom
&right
是元素底部(/右侧)相对于窗口顶部(/右侧)的距离,不是像css里面position的bottom相对于窗口底部。
参考文章: