【小贴士】虚拟键盘与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 ...
随机推荐
- Lua 学习笔记(一)环境搭建
Lua是一个小巧的脚本语言.Lua由标准C编写而成,代码简洁,几乎在所有的操作系统和平台上都可以编译,运行. 主要讲一下mac和win下的环境搭建. 工具: 1.Sublime Text 2 ...
- PHP的学习--Traits新特性
在阅读yii2源码的时候接触到了trait,就学习了一下,写下博客记录一下. 自 PHP 5.4.0 起,PHP 实现了代码复用的一个方法,称为 traits. Traits 是一种为类似 PHP 的 ...
- 【web前端面试题整理05】做几道前端面试题休息休息吧
前言 连续学了两天javascript的东西了,我们都累了,于是今天还是上一套面试题吧,大家一起休息休息,也为下个星期可能会有的面试准备下. 题目一览 CSS1. overflow-x 属于 CS ...
- Primer – 支撑 GitHub 的 CSS 工具包和准则
Primer 是一个 CSS 工具包,支撑着 GitHub 的前端设计.它的目的仅限于提供通用部件,为我们的开发者提供最大的灵活性,并保持 GitHub 的独特风格.它基于 SCSS 建成,可以通过 ...
- Gumby – 基于 Sass 的灵活的,响应式 CSS 框架
Gumby 框架是一个基于 SASS 的灵活的,响应式的 CSS 框架.可以借助其灵活,响应式的网格系统和 UI 套件快速创建逻辑的页面布局和应用程序原型. 您可能感兴趣的相关文章 35个让人惊讶的 ...
- Elasticsearch增删改查 之 —— mget多文档查询
之前说过了针对单一文档的增删改查,基本也算是达到了一个基本数据库的功能.本篇主要描述的是多文档的查询,通过这个查询语法,可以根据多个文档的查询条件,返回多个文档集合. 更多内容可以参考我整理的ELK文 ...
- Redis 集群方案
根据一些测试整理出来的一份方案(转自http://www.cnblogs.com/lulu/): 1. Redis 性能 对于redis 的一些简单测试,仅供参考: 测试环境:Redhat6.2 , ...
- JS数字键盘
JS数字键盘,JS小键盘 CSS代码: #numberkeyboard { border: 1px solid #b3b3b3; background: #f2f3f7; height: 285px; ...
- ASP.NET 的IP帮助类
个人网站地址: https://www.lesg.cn/netdaima/net/2016-239.html ASP.NET 的IP帮助类 在Web开发中会出现需要调用客户IP的方法: 一般调用方法就 ...
- iOS 阶段学习第11天笔记(OC基础知识)
iOS学习(OC语言)知识点整理 一.OC基础知识 1)#import 用于导入头文件,预处理阶段加载引用,只加载一次. 2)OC 依赖于Foundation框架下的头文件Foundation.h, ...