移动端那些戳中你痛点的软键盘问题及解决方法

发表于 3年以前  | 总阅读数:614 次

问题

问题描述:

在ios手机中,当页面中包含有输入框时,点击输入框,键盘弹起,会让页面中被fixed的元素失效。所以造成了底部吸底和顶部吸顶的元素错位的问题。下面的视频中就出现了这个问题,吸顶元素被推到可视区之外去了,而吸底元素也被推到了键盘之上。

Gif 如下:

ui希望优化的点:

一开始,ui针对这个视频中出现的问题,提出了3个优化点:

1、希望吸顶元素能够继续吸顶

2、希望吸底元素能够继续吸底

3、希望当键盘弹起之后,输入框能够保持在键盘之上48px的距离

最终决定优化的点:

经过一番调研,在我搜集到的可行方法中,结合有限的时间因素,在和ui协调之后,将这3个优化点变成了下面这3个优化点。同时还参考网上文章,增加了一些特殊情况下可能出现问题的优化点。

1、吸顶元素能够继续吸顶

2、吸底元素(也就是按钮)能够在键盘弹出之后,出现在键盘的上方

3、键盘弹起,输入框出现在可视区内。(对于这点,ios本身是支持的,但是安卓却并不会主动让输入框出现在可视区域内)

4、对于部分ios系统下的部分微信webview内,发现软键盘收起时,滚动上去的页面没有滚动下来,造成了下面区域留出了一片灰色的区域。

先要弄懂的问题

解决这些问题之前,需要弄明白以下2个问题:

1、当键盘弹起来的时候,会发生什么

这里ios和安卓系统下表现的并不一致。这个参考了朱雷大佬提供的这个文章:WebView上软键盘的兼容方案[1]

IOS 软键盘弹起表现

在 IOS 上,输入框(input、textarea 或 富文本)获取焦点,键盘弹起,页面(webview)并没有被压缩,或者说高度(height)没有改变,只是页面(webview)整体往上滚了,且最大滚动高度(scrollTop)为软键盘高度。

Android 软键盘弹起表现

同样,在 Android 上,输入框获取焦点,键盘弹起,但是页面(webview)高度会发生改变,一般来说,高度为可视区高度(原高度减去软键盘高度),除了因为页面内容被撑开可以产生滚动,webview本身不能滚动。

IOS 软键盘收起表现

触发软键盘上的“收起”按钮键盘或者输入框以外的页面区域时,输入框失去焦点,软键盘收起。

Android 软键盘收起表现

触发输入框以外的区域时,输入框失去焦点,软键盘收起。但是,触发键盘上的收起按钮键盘时,输入框并不会失去焦点,同样软键盘收起。

2、为什么fixed会失效

既然ios键盘弹起时,页面会上移,那么为什么fixed会失效呢。

这里参考这篇文章:ios键盘难题与可见视口(visualViewport)api[2]

当时ios设计者考虑到一个问题:当键盘弹起时,页面无法感知到键盘的存在。那么,如果将要输入的目标(即「输入框」,例如 input、textarea 或一般的 contenteditable 元素)正好被弹起的键盘遮住,体验不会很糟糕吗?

为了解决这个问题,ios设计者们让webview上滚,但滚动的结果有些出乎意料:输入框本身可以理解地滚动到了实际可视区域的正中间,但 fixed 元素不会发生重新计算,而是保持原来的相对位置,跟着输入框一起被上推;在滚动过程中,还会允许屏幕底部超出页面底部(「滚动过头」),以便让输入框尽可能露出来。收起键盘后,「滚动过头」的部分会被弹回,fixed 元素发生重新计算,但页面并不会回到与打开键盘前相同的位置。

3、怎么监听键盘弹起和收起的动作

既然是键盘弹起来造成的问题,那么解决这个问题必然需要监听键盘弹起和收起的动作,那怎么监听呢。同样参考这篇文章:WebView上软键盘的兼容方案[3]

综合上面键盘弹起和收起在 IOS 和 Android 上的不同表现,我们可以分开进行如下处理来监听软键盘的弹起和收起:

Ios

在 IOS 上,监听输入框的 focus 事件来获知软键盘弹起,监听输入框的 blur 事件获知软键盘收起。在 Android 上,监听 webview 高度会变化,高度变小获知软键盘弹起,否则软键盘收起。

// IOS 键盘弹起:当输入框被聚焦时IOS键盘会被弹起
  inputRef?.current?.addEventListener('focus', function () {
    // IOS 键盘弹起后操作
  }, false)

  // IOS 键盘收起:当点击输入框以外区域或点击收起按钮,IOS输入框都会失去焦点,键盘会收起,
  inputRef?.current?.addEventListener('blur', () => {
    // IOS 键盘收起后操作
  })

android

在 Android 上,监听 webview 高度变化,高度变小获知软键盘弹起,否则软键盘收起。

ndroid
在 Android 上,监听 webview 高度变化,高度变小获知软键盘弹起,否则软键盘收起。

useEffect(() => {
    const { isAndroid } = Util.getOS('');
    let originHeight = document.documentElement.clientHeight || document.body.clientHeight;
    const handelAndroidResize = throttle(() => {
        const resizeHeight =
            document.documentElement.clientHeight || document.body.clientHeight;
        if (originHeight < resizeHeight) {
            // Android 键盘收起后操作
        } else {
            // Android 键盘弹起后操作
        }
        originHeight = resizeHeight;
    }, 300);

    if (isAndroid) {
        window.addEventListener('resize', handelAndroidResize, false);
    }

    return () => {
        if (isAndroid) {
            window.removeEventListener('resize', handelAndroidResize, false);
        }
    };
  }, []);

解决办法

下面就开始一一对上面说的问题进行分析解决:

1、吸顶元素能够继续吸顶

这个问题因为键盘弹出ios和安卓的处理方式不同,这个现象就只发生在ios系统中。

当时找了一圈方法,觉得并没有合适的解决方法,退而求其次,既然h5无没有办法很好的解决吸顶问题,那么这个能力不如就用客户端的能力好了,客户端的header不属于webview内容,自然webview上推时,客户端的header就还是吸顶状态。

我们当时的情况下,客户端的jsb能力只能够支持简单的一个返回按钮加一个居中标题作为header。所以有右上角的“历史评价”就不能够直接用jsb能力写,所以只能和ui同学商量,将原本的设计方案改一下。变成如下设计,就能够使用jsb能力写header了。

衍生问题:

但这样引出了一个新的问题:在安卓系统下的app端,会有底部按钮被遮挡的问题。

GIF 如下:

衍生问题解决办法

之前header头用的是前端自己写的header时,没有这个问题,推测是因为安卓手机在键盘弹起时的webview高度缩短为整个屏幕的高度减去键盘的高度, 在之前的实现中,由于使用沉浸式header,所以前端webview高度就是整个屏幕的高度,而现在由于采用的是客户端jsb能力,所以webview剩余高度就需要减去header头的高度。所以解决办法就是让键盘弹起时,添加吸底按钮以及底部元素的margin-bottom为header的高度就行。

2、吸底元素(也就是按钮)能够在键盘弹出之后,出现在键盘的上方

对于这个问题,因为安卓表现是webview缩小,所以在安卓上并不存在这个问题,对于ios,因为ios向上滚动的距离最大是键盘的高度,但是也有可能滚动距离不是键盘高度,导致吸底按钮会被遮挡。

可见 GIF 如下:

解决办法:

让键盘弹起来的时候,让输入框加入scrollIntoView(true);方法。这其实可能只适用于我这种情景,这个解决办法的原理是:scrollIntoView(true)想让输入框的顶部滚动到与可视区顶部齐平的效果,但是由于ios键盘弹起之后最大滚动距离等于键盘的高度,所以,通过这个方法会让webview滚动距离等于ios键盘的高度,达到了吸底按钮吸底的效果。

3、键盘弹起,输入框出现在可视区内。(对于这点,ios本身是支持的,但是安卓却并不会主动让输入框出现在可视区域内)

这个简单,让元素滚动到可视区内,直接用scrollIntoView(true)方法就好。

4、ios软键盘收起时页面不能自然滑落

对于部分ios系统下的部分微信webview内,发现软键盘收起时,滚动上去的页面没有滚动下来,造成了下面区域留出了一片灰色的区域。其实这是 Apple 在 IOS 的 bug,会出现在所有的 Xcode10 打包的 IOS12 的设备上。微信官方已给出解决方案(点击查看[4])。

问题gif:

如图所示:

解决办法:

当键盘收起时,加入下面其中一种办法就可以解决

1 . 滚动到顶部

window.scrollTo(0,0)

2 . 滚动到底部

window.scrollTo(0, Math.max(document.body.clientHeight, document.documentElement.clientHeight));

本场景代码

const handleIosInputBlur = () => {
    // IOS 键盘收起后操作
    // 微信浏览器版本6.7.4+IOS12会出现键盘收起后,视图被顶上去了没有下来
    const wechatInfoRe = /MicroMessenger\/([\d\.]+)/i;
    const wechatInfo = wechatInfoRe.exec(window?.navigator?.userAgent);
    const wechatVersion = wechatInfo && wechatInfo.length > 1 && wechatInfo[1];

    const osInfoRe = /OS (\d+)_(\d+)_?(\d+)?/i;
    const osInfo = osInfoRe.exec(navigator.appVersion);
    const osVersion = osInfo && osInfo.length > 1 && osInfo[1];

    if (!wechatVersion || !osVersion) {
        return;
    }
    const height = Math.max(document.body.clientHeight, document.documentElement.clientHeight);
        if (Number(wechatVersion.replace(/\./g, '')) >= 674 && Number(osVersion) >= 12) {
            window.scrollTo(0, height);
        }
    };

最终效果:

Ios

安卓

参考文章:

WebView上软键盘的兼容方案[5]

js如何获取iOS键盘高度[6]

移动端input“输入框”常见问题及解决方法[7]

ios键盘难题与可见视口(visualViewport)api[8]

参考资料

[1]WebView上软键盘的兼容方案: https://setcina.github.io/2020/01/20/WebView%E4%B8%8A%E8%BD%AF%E9%94%AE%E7%9B%98%E7%9A%84%E5%85%BC%E5%AE%B9%E6%96%B9%E6%A1%88/

[2]ios键盘难题与可见视口(visualViewport)api: http://www.alloyteam.com/2020/02/14265/comment-page-1/#prettyPhoto

[3]WebView上软键盘的兼容方案: https://setcina.github.io/2020/01/20/WebView%E4%B8%8A%E8%BD%AF%E9%94%AE%E7%9B%98%E7%9A%84%E5%85%BC%E5%AE%B9%E6%96%B9%E6%A1%88/

[4]点击查看: https://developers.weixin.qq.com/community/develop/doc/00044ae90742f8c82fb78fcae56800

[5]WebView上软键盘的兼容方案: https://setcina.github.io/2020/01/20/WebView%E4%B8%8A%E8%BD%AF%E9%94%AE%E7%9B%98%E7%9A%84%E5%85%BC%E5%AE%B9%E6%96%B9%E6%A1%88/

[6]js如何获取iOS键盘高度: https://zhuanlan.zhihu.com/p/359955143

[7]移动端input“输入框”常见问题及解决方法: https://www.huaweicloud.com/articles/979b05af7fa9b4382bfc1e408f7d0067.html

[8]ios键盘难题与可见视口(visualViewport)api: http://www.alloyteam.com/2020/02/14265/comment-page-1/#prettyPhoto

本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/M07Ky3FHcb0rpr7u-NRlMA

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  237231次阅读
vscode超好用的代码书签插件Bookmarks 2年以前  |  8065次阅读
 目录