【小贴士】虚拟键盘与fixed带给移动端的痛!
前言
今天来公司的主要目的就是研究虚拟键盘与fixed的问题,期间因为同事问起闭包与事件委托(阻止冒泡)相关问题,便穿插了一篇别的:
【小贴士】工作中的”闭包“与事件委托的”阻止冒泡“,有兴趣的朋友可以去看看,因为首页只能放一篇,这个就略去了
现在回到主要研究点,首先在移动端我们点击文本框后会出现一个虚拟键盘, 虚拟键盘让页面可视区域得到了充分利用,但是也带来了一些问题
问题源头
移动端虚拟键盘出现的条件是:文本框(文本类)获得焦点
但是文本框获得焦点未必会弹出键盘!!!
收起虚拟键盘的条件是:文本框失焦
PS:总而言之,我们认为会出现或者消失虚拟键盘的时候都可能不工作
在移动设备上,如果文本框在上方,点击不会有什么问题:
在设备的最下面的话,就有所不同了,整个块会上移,以将input区域显示出来
这个时候几个棘手的问题就出现了:
① 虚拟键盘的出现对页面来说是不可知的,这句话的理解是:没有键盘出现事件,没有办法获取键盘高度
② 键盘是“贴”在了viewport上,表面上不会对dom产生“任何”影响,但是这个时候一些定位元素的表现却变得“怪异”
比如:


可以看到,无论淘宝或者新浪,这个问题都存在,现在比较普遍的解决方案都是:移动端不采用fixed属性
于是我们来看看是否有其它方案
iscroll是否能解决
其实这个方案在周四的时候我便测试过了,但是结果让人很遗憾

作为官方给出的例子,在虚拟键盘弹出来后,光标会乱跑,这个还可以接受,但是:
① 头部不见了
② 偶尔不能显示获得焦点的input
这两个问题就让人难以接受了,于是,我们需要找到其他方案
解决方案
其实这个问题如果真要较真的话,我觉得需要深入研究两个知识点:
① viewport的原理
② 虚拟键盘的原理
就我手里现有资源来说,两个知识点一个都不深入,所以只能先从应用层面解决问题
应用层面解决方案
我们想到这么一个场景,如果我们能监控到键盘的行为,如果能的话,我们便可以
① 键盘弹出时候将fixed元素设置为static
② 键盘消失时候将fixed元素设置为fixed
那么我们能吗???
虽然这个方案比较恶心,我们还真能......答案是监控dom变化!
监控键盘
监控的方式其实筛选下来也不过两种:
① 时钟setInterval不停监控
② 系统级别的监控,比如键盘出现时候通知window一个事件,但是很遗憾现在还没有这个事件,但是这个事件等于
input类元素获取焦点 == 弹出虚拟键盘
input类元素失去焦点 == 收起虚拟键盘
但是我们前面已经说过,上面的原则不一定可靠,所以该种方案也未必可靠了
基于系统监控这点,我们还可以监控resize事件或者scroll事件,但是经过我的测试,setInterval表现比较好
于是,我们简单写一段代码,可靠是否满足需求:
window.alert = function (msg) {
$('body').append('<div>' + msg + '</div>')
};
function fixedWatch(el) {
if(document.activeElement.nodeName == 'INPUT'){
el.css('position', 'static');
} else {
el.css('position', 'fixed');
}
}
setInterval(function () {
fixedWatch($('#headerview header'));
}, 500);
根据测试结果来说,是满足我们的需求的,这里的header不会出问题,但是footer由于没有处理仍然会错位

于是这个问题似乎被我们修复了,但是你可以接受吗???这个方案有一个致命的恶心点!
不停的监控dom变化,浪费资源
那么这个问题可优化么?
似乎是可优化的,但是依旧会带来很多问题,优化的入口与出口便是input标签的focus事件
至于其失焦相关的事件便不予关注了,因为可能由一个input跳到另一个input
setTimeout(function () {
$('#dl_app img').hide();
}, 100);
window.alert = function (msg) {
$('body').append('<div>' + msg + '</div>')
};
window.res = null;
var i = 0;
function fixedWatch(el) {
alert(i++);
if(document.activeElement.nodeName == 'INPUT'){
el.css('position', 'static');
} else {
el.css('position', 'fixed');
if(window.res ) { clearInterval(window.res ); window.res = null; }
}
}
$('input').focus(function () {
if(!window.res) {
fixedWatch($('#headerview header'));
window.res = setInterval(function () {
fixedWatch($('#headerview header'));
}, 500);
}
});
这样的话,貌似能让代码看上去舒服一点,但是其代价却是所有input类标签都会多一个获得焦点事件,依旧令人痛惜
结语
今天的学习暂时到此,对于虚拟键盘的出现其实可能还有其他的问题,举一个例子来说:
如果我们点击按钮时候会出一个toast在中间,但是虚拟键盘刚好遮住了toast提示信息怎么办呢?这个问题与上述问题其实是一致的
然后这个解决方案的可接受程度,以及其实际是否解决了问题又或者引起了其它问题就需要实际证明了
至于各位有什么好的解决方案,或者想法,可以讨论讨论哦!!!
好了,今天暂时到这里,我们下次继续,如果有可能我们会详细学习下viewport以及虚拟键盘相关
【小贴士】虚拟键盘与fixed带给移动端的痛!的更多相关文章
- ios的虚拟键盘与fixed移动端的bug
//$('#search')表单input;$('.search_out')浮动元素 var u = navigator.userAgent, app = navigator.appVersion;v ...
- 【转】air调用windows自带的虚拟键盘
原文:http://bbs.9ria.com/blog-73243-19560.html 最近在做一个东西,需要用到虚拟键盘.刚开始准备用as3开发一套,结果突然想起来windows有个自带的虚拟键盘 ...
- ios设备触发虚拟键盘输入后position:fixed 无效的一些简单另类的解决方法。
首先看一下我要解决的问题,第一张图是正常的情况下,第二张图是点击了输入框之后的情况,就是要解决此问题~! 百度了一下解决方法,好像有以下的一些方法: 1. iscroll 2. Jquery Mobi ...
- 在移动端H5开发中(关于安卓端position:fixed和position:absolute;和虚拟键盘冲突的问题,以及解决方案)
一.在开发移动端webapp时,我们经常会遇到这样的问题,当我们需要在页面底部固定一个logo或者说明时,往往会采用position:fixed进行固定定位或者absolute定位到最底部 这是一个很 ...
- 【小贴士】zepto find元素以及ios弹出键盘可能让你很头疼
前言 在此,我不得不说移动端的兼容问题很多,并且很令人头疼,这不,这个星期又有两个让我逮着了,一个是使用zepto过程中出现的问题,一个是ios虚拟键盘的问题 我这里做一次记录,以免以后忘了,同时希望 ...
- C#调用Windows(8/10)自带的虚拟键盘
以下是调用代码: private const Int32 WM_SYSCOMMAND = 274; private const UInt32 SC_CLOSE = 61536; [DllImport( ...
- H5 IOS 虚拟键盘不回落的问题
在 H5 页面中,会发现在高版本的 IOS 系统中(ios12以上)和微信版本6.7.x以上,都会发现 input 等输入框,输入内容之后发现虚拟键盘消失,但是页面出现大面积白框. 解决办法(最后加上 ...
- android性能小贴士 翻译
转自http://developer.android.com/training/articles/perf-tips.html 性能小贴士: 这篇文档主要一些微优化可以提升应用程序性能,但是这些改变不 ...
- 隐藏虚拟键盘,解决键盘挡住UITextField问题
再正式开始之前,先来介绍一下IOS的键盘类型: 一.键盘风格 UIKit框架支持8种风格键盘 ? 1 2 3 4 5 6 7 8 9 10 typedef enum { UIKeyboard ...
随机推荐
- 依赖注入(DI)与服务容器(IoC)
参考文章:http://www.yuansir-web.com/2014/03/20/%E7%90%86%E8%A7%A3php-%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A ...
- JSP网站开发基础总结《一》
经过JAVASE的学习相信大家对JAVA已经不再陌生,那么JAVA都可以干什么呢?做算法.应用程序.网站开发都可以,从今天开始为大家奉上JAVAEE之JSP动态网站开发基础总结. 既然是动态网站开发, ...
- poj2513Colored Sticks(无向图的欧拉回路)
/* 题意:将两端涂有颜色的木棒连在一起,并且连接处的颜色相同! 思路:将每一个单词看成一个节点,建立节点之间的无向图!判断是否是欧拉回路或者是欧拉路 并查集判通 + 奇度节点个数等于2或者0 */ ...
- ViewPager的缓存机制
1.实现Viewpager的页面懒加载: 在某些情况下,例如使用ViewPager查看多张大图,此时多张图片不能一次性载入,只有在浏览该页面时才载入(或者预先载入下一页面)页面的具体内容. 2.可控V ...
- [Python] urllib2.HTTPError: HTTP Error 403: Forbidden
搬运自http://www.2cto.com/kf/201309/242273.html,感谢原作. 之所以出现上面的异常,是因为如果用 urllib.request.urlopen 方式打开一个UR ...
- Redis持久化方法对比分析
1.前言 最近在项目中使用到Redis做缓存,方便多个业务进程之间共享数据.由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能, ...
- git代码回滚:Reset、Checkout、Revert的选择
代码回滚:Reset.Checkout.Revert的选择 Zhongyi Tong edited this page on Dec 8, 2015 · 5 revisions Pages 19 Ho ...
- jQuery源码解读-事件分析
最原始的事件注册 addEventListener方法大家应该都很熟悉,它是Html元素注册事件最原始的方法.先看下addEventListener方法签名: element.addEventList ...
- Unicode中文和特殊字符的编码范围
编程中有时候需要用到匹配中文的正则,一般用 [ \u4e00-\u9fa5]+ 即可搞定.不过这正则对一般的火星文鸟语就不太适用了,甚至全角的标点符号都不包含在内.例如游戏里面的玩家名,普通青年一般都 ...
- java的if else语句入门
条件语句,是程序中根据条件是否成立进行选择执行的一类语句,这类语句在实际使用中,难点在于如何准确的抽象条件.例如实现程序登录功能时,如果用户名和密码正确,则进入系统,否则弹出“密码错误”这样的提示框等 ...