前言

今天来公司的主要目的就是研究虚拟键盘与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带给移动端的痛!的更多相关文章

  1. ios的虚拟键盘与fixed移动端的bug

    //$('#search')表单input;$('.search_out')浮动元素 var u = navigator.userAgent, app = navigator.appVersion;v ...

  2. 【转】air调用windows自带的虚拟键盘

    原文:http://bbs.9ria.com/blog-73243-19560.html 最近在做一个东西,需要用到虚拟键盘.刚开始准备用as3开发一套,结果突然想起来windows有个自带的虚拟键盘 ...

  3. ios设备触发虚拟键盘输入后position:fixed 无效的一些简单另类的解决方法。

    首先看一下我要解决的问题,第一张图是正常的情况下,第二张图是点击了输入框之后的情况,就是要解决此问题~! 百度了一下解决方法,好像有以下的一些方法: 1. iscroll 2. Jquery Mobi ...

  4. 在移动端H5开发中(关于安卓端position:fixed和position:absolute;和虚拟键盘冲突的问题,以及解决方案)

    一.在开发移动端webapp时,我们经常会遇到这样的问题,当我们需要在页面底部固定一个logo或者说明时,往往会采用position:fixed进行固定定位或者absolute定位到最底部 这是一个很 ...

  5. 【小贴士】zepto find元素以及ios弹出键盘可能让你很头疼

    前言 在此,我不得不说移动端的兼容问题很多,并且很令人头疼,这不,这个星期又有两个让我逮着了,一个是使用zepto过程中出现的问题,一个是ios虚拟键盘的问题 我这里做一次记录,以免以后忘了,同时希望 ...

  6. C#调用Windows(8/10)自带的虚拟键盘

    以下是调用代码: private const Int32 WM_SYSCOMMAND = 274; private const UInt32 SC_CLOSE = 61536; [DllImport( ...

  7. H5 IOS 虚拟键盘不回落的问题

    在 H5 页面中,会发现在高版本的 IOS 系统中(ios12以上)和微信版本6.7.x以上,都会发现 input 等输入框,输入内容之后发现虚拟键盘消失,但是页面出现大面积白框. 解决办法(最后加上 ...

  8. android性能小贴士 翻译

    转自http://developer.android.com/training/articles/perf-tips.html 性能小贴士: 这篇文档主要一些微优化可以提升应用程序性能,但是这些改变不 ...

  9. 隐藏虚拟键盘,解决键盘挡住UITextField问题

    再正式开始之前,先来介绍一下IOS的键盘类型: 一.键盘风格 UIKit框架支持8种风格键盘 ? 1 2 3 4 5 6 7 8 9 10 typedef enum {      UIKeyboard ...

随机推荐

  1. HTML5之废弃和更新的元素与属性

    废弃的元素和属性 [1]标签替换 <acronym> 替代:<abbr> <applet> 替代:<embed> 或 <object> &l ...

  2. js让程序暂停一段时间再执行

    function sleep(d){ for(var t = Date.now();Date.now() - t <= d;); } sleep(5000); //当前方法暂停5秒

  3. Android进程间通信之socket通信

    用Java中的socket编程. 通过socket实现两个应用之间的通信,可以接收和发送数据,同时将接收到的数据显示在activity界面上. Server端: ServerLastly.java p ...

  4. Network - FTP与SFTP

    FTP --- FTP File Transfer SFTP --- SSH File Transfer 缩写 名称 协议与端口 安全策略 特征描述 守护进程(linux) 应用场景 SFTP SSH ...

  5. HTML Inspector – 帮助你编写高质量的 HTML 代码

    HTML Inspector 是一款代码质量检测工具,帮助你编写更优秀的 HTML 代码.HTML Inspector 使用 JavaScript 编写,运行在浏览器中,是最好的 HTML 代码检测工 ...

  6. JS兼容所有浏览器的一段加入收藏代码,设置为首页

    <script language="javascript" type="text/javascript"> function addfavorite ...

  7. 实例演示Android异步加载图片

    本文给大家演示异步加载图片的分析过程.让大家了解异步加载图片的好处,以及如何更新UI.首先给出main.xml布局文件:简单来说就是 LinearLayout 布局,其下放了2个TextView和5个 ...

  8. Windows Azure Web Site (1) 用户手册

    <Windows Azure Platform 系列文章目录> 下载地址: Web Apps用户手册

  9. [Azure附录]1.在Windows Server 2012中安装Active Directory域服务

    <Windows Azure Platform 系列文章目录> 1.登陆Windows Server 2012,打开服务器管理器,选择"添加角色和功能" 2.在&quo ...

  10. js基础-表单验证和提交

    基础知识: 原始提交如下: <form action="/login" method="post" id="form1"> &l ...