【小贴士】虚拟键盘与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以及虚拟键盘相关



本文转自叶小钗博客园博客,原文链接http://www.cnblogs.com/yexiaochai/p/3561939.html,如需转载请自行联系原作者

相关文章
|
2月前
|
开发者 前端开发 编解码
Vaadin解锁移动适配新境界:一招制胜,让你的应用征服所有屏幕!
【8月更文挑战第31天】在移动互联网时代,跨平台应用开发备受青睐。作为一款基于Java的Web应用框架,Vaadin凭借其组件化设计和强大的服务器端渲染能力,助力开发者轻松构建多设备适应的Web应用。本文探讨Vaadin与移动设备的适配策略,包括响应式布局、CSS媒体查询、TouchKit插件及服务器端优化,帮助开发者打造美观且实用的移动端体验。通过这些工具和策略的应用,可有效应对屏幕尺寸、分辨率及操作系统的多样性挑战,满足广大移动用户的使用需求。
42 0
|
2月前
|
编解码 UED
揭秘!响应式设计的神奇魔法,如何让网站在无数屏幕上跳舞?
【8月更文挑战第6天】随着移动互联网的发展,屏幕尺寸多样化,传统固定布局不再适用。响应式设计应运而生,旨在让网站适应各种设备,提供一致的优质体验。本文通过重构企业官网案例,展示如何运用媒体查询、流式与弹性盒子布局等技术,实现导航、内容及图片的自适应调整。例如,在小屏幕下隐藏导航,内容区扩展至全宽,并根据不同分辨率提供相应大小的图片,确保加载速度与显示质量。最终,实现了跨设备的一致性体验,体现了从用户体验出发的设计理念。
29 2
|
4月前
|
监控 C#
技术经验解读:【转】c#实现魔兽(warIII)中显血和改键功能(附源码)(不影响聊天打字)
技术经验解读:【转】c#实现魔兽(warIII)中显血和改键功能(附源码)(不影响聊天打字)
79 0
|
5月前
|
前端开发 JavaScript API
|
12月前
|
Java C# Android开发
关于移动端,我回忆和思考了一下
关于移动端,我回忆和思考了一下
|
存储 算法 定位技术
千耘导航QYX—明明有颜值,硬要靠实力
随着太阳活动峰年的到来,电离层的活跃程度在逐步加剧,是否担心因受电离层活跃的干扰,出现农机导航定位精度不准甚至不能用的情况? 千耘QYX电离层抑制能力,可有效降低电离层活跃对农机导航的影响,保障用户使用农机导航过程中精度的稳定性。
千耘导航QYX—明明有颜值,硬要靠实力
|
Java
手把手一步一步教你使用Java开发一个大型街机动作闯关类游戏20之enemy被攻击显示后退动画(block效果)
手把手一步一步教你使用Java开发一个大型街机动作闯关类游戏20之enemy被攻击显示后退动画(block效果)
161 0
|
移动开发 前端开发 API
本周推荐 | 基于 canvas 实现 H5 丝滑看图体验
推荐语:随着机器算力及性能的提升,基于原生Web体系的富交互体验也可以媲美原生,本文作者通过Canvas + Web手势从零实现了大图浏览的交互效果,并在体验上不输Native,是一次不错的技术尝试,欢迎阅读。 ——大淘宝技术客户端开发工程师 楚奕
333 0
本周推荐 | 基于 canvas 实现 H5 丝滑看图体验
|
前端开发 JavaScript 小程序
印象最深的一个bug——使用uinapp做混合开发静态图片在安卓端不显示
这几天一直在做混合开发,使用的是uni-app开发的,一套代码,多端使用,适用于各个平台。听起来很完美,使用过程不可多说,不知道是因为我们的需求变态还是我们团队两端技术水平太差。总之,开发联调过程十分痛苦,加上uniapp的调试十分困难,一度让我们两端互怼。这其中我印象最深的一个bug就是在对接联调总出现的
1665091 33
印象最深的一个bug——使用uinapp做混合开发静态图片在安卓端不显示
|
JavaScript Android开发 数据安全/隐私保护
移动端爬坑记 --- (1)布局与样式上的奇葩偶遇
Flex想要兼容众多花样式手机,要注意以下这么些 • 前缀要考虑2009~2012年的语法[webkit-box,flex,flex-box] • 少用复合属性,比如flex:1,考虑兼容理应拆成[flex-grow,flex-shrink,flex-basis];flex-flow拆开成[flex-direction,flex-wra
141 0