移动端调起软键盘导致 position:fixed 偏移

更新日期: 2019-08-25阅读: 5.2k标签: 键盘

1. 问题描述

app内打开H5页面,页面包含input输入框,点击input调起软键盘,输入完成点击下方提交按钮弹出toast时,会出现t toast 跳动的现象,其中:toast采用 position: fixed 进行固定定位


2. 分析原因

关于 position: fixed

首先来看,MDN 中对 position: fixed 的说明:

不为元素预留空间,而是通过指定元素相对于屏幕视口(viewport)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变。

注意到,position: fixed 是相对屏幕视口(viewport)的位置来定位的。 那么toast跳动是否是因为 viewport 的改变呢?


关于 viewport

MDN 中对 viewport 的说明:

@viewport 规则让我们可以对文档的大小进行设置 viewport 。这个特性主要被用于移动设备。 按百分比计算尺寸的时候,就是参照的初始视口(viewport)。初始视口指的是任何用户代理和样式对它进行修改之前的视口。桌面浏览器如果不是全屏模式的话,一般是基于窗口大小。

在移动设备上(或者桌面浏览器的全屏模式),初始视口通常就是应用程序可以使用的屏幕部分。它可能是全屏或者减去由操作系统或者其它应用程序所占用的部分(例如状态栏)

我们注意到,viewport 是会随着操作系统或者应用程序占用而变化的,那是不是在调起软键盘的时候,改变了viewport 呢


验证猜想

js 提供了Window.innerHeight 方法,用来获取浏览器窗口的视口高度。
经过验证,在调起软键盘时,确实改变了viewport ,此时的视口高度是 我们看到的可视屏幕高度-键盘高度, 所以我们看到的toast跳动是因为 viewport的改变而导致。


3. 解决办法

通过绝对定位position: absolute 来替代 position: fixed

通常 toast 是直接插入到body元素下面的(当然可以是别的任何元素),即 toast 是body元素的直接子元素,因此,可以设置toast 相对body元素进行绝对定位。

代码如下:


body {
    position: relative;
}
.toast {
   //  固定屏幕中间
    position: absolute;
    top: 50%; 
    left: 50%;
    transform: translate3d(-50%,-50%,0);
}


4. 注意事项

在使用通过绝对定位position: absolute 来替代 position: fixed的解决方案时,如果top、left 设置百分比,就需要注意设置绝对定位元素的 offsetParent 的 height 及 width 值。

因为,绝对定位是相对离它最近的position 属性值不为static的父元素(即 offsetParent )来进行定位,并且top、left 设置百分比是以offsetParent 的height 和 width 来计算的。

比如上述动图中的例子,可以看到body的内容高度远远不到屏幕高度,因此想要实现 toast 在屏幕居中,就需要为 body元素设置合理的高度(通过设置 min-height 或者 height )。

上述例子的完整代码:

html{
    height: 100%;  // 设置html为浏览器窗口高度(不设100%的话,html 高度就等于body的高度)
}
body {
    position: relative;
    min-height: 600px;  // 设置最小高度
}
.toast {
   //  固定屏幕中间
    position: absolute;
    top: 50%; 
    left: 50%;
    transform: translate3d(-50%,-50%,0);
}

offsetParent 概念补充

The HTMLElement.offsetParent read-only property returns a reference to the object which is the closest (nearest in the containment hierarchy) positioned containing element. If the element is non-positioned, the nearest td, th, table or the body is returned.


5. 总结

针对移动端调起软键盘导致 position:fixed 偏移的问题,可以通过绝对定位(position: absolute)替代固定定位( position:fixed)来曲线救国。 如果topleft 设置百分比,则同时注意设置绝对定位元素的 offsetParent 的height和 width 值。

链接: https://fly63.com/article/detial/5045

html的原生自定义键盘(数字版)

前端现在很多时候,由于要限制文本的输入格式(这里指只允许输入数字),常常需要使用到自定义键盘。自定义键盘难免涉及到复用,资源占用等问题,有时候还会由于封装不好导致事件混乱、或者由于动画效果没实现好导致看上去很尴尬

移动端input框被虚拟键盘挡住的js解决方法

在webapp开发过程中,当用户切换输入法额时候,会出现输入框被弹起的虚拟键盘遮挡住的情况,这时用户输入只能盲填 ,这会验证影响用户体验。

微信小程序仿input组件、虚拟键盘

仿照微信支付界面,金额输入框不能用input;要有光标,点击输入框调起虚拟键盘,点击输入框以外的地方隐藏输入框;第一个输入的是小数点要补全,比如:第一个输入的是小数点,则输入框显示为 0. ;

ionic开发中,输入法键盘弹出遮挡住div元素

采用ionic 开发中,遇到键盘弹出遮挡元素的问题。以登陆页面为例,输入用户名和密码时,键盘遮挡了登陆按钮。引用:将命名好的指令名 :popupKeyBoardShow,按驼峰拆开用-连接成小写,如:popup-key-board-show。

关于ios的光标和键盘回弹问题

最近再做项目的时候(移动端),遇到了两个小问题,一个是ios端键盘不回弹的问题(微信浏览器),另一个是ios输入光标位置问题。就是点击一个按钮,要把输入框里面原来的内容加上一些固定的内容,然后一起输出到输入框。

可能这些是你想要的H5软键盘兼容方案

最近一段时间在做 H5 聊天项目,踩过其中一大坑:输入框获取焦点,软键盘弹起,要求输入框吸附(或顶)在输入法框上。需求很明确,看似很简单,其实不然。从实验过一些机型上看,发现主要存在以下问题:

解决微信H5页面软键盘弹起后页面下方留白的问题(iOS端)

微信H5项目,ios端出现了软键盘输完隐藏后页面不会回弹,下方会有一大块留白 最近微信和ios都有版本升级,不知道是哪边升级造成的,但是经过测试,软键盘收起后,再滚动一下页面,下面的留白就会消失

为什么程序员使用电脑时,很少使用鼠标,只需要键盘就能工作?

现在很多人在使用电脑的时候会特别依赖鼠标,因为使用鼠标操作会比较方便,身边有程序员的人可能会疑惑为什么他们在使用电脑的时候,不需要鼠标,只需要一个键盘就能工作了呢?

通过focusout事件解决IOS键盘收起时界面不归位的问题

今天在开发一个移动端的 H5 页面时,遇到了 IOS 上键盘收起时界面无法归位的问题。下面详细描述下问题和症状:出问题的页面是一个表单结构。即类似于一个 div 下有4个 input 表单的结构

vue中监听返回键

在项目中,我们常常有需求,当用户在填写表单时,点击返回的时候,我们希望加一个弹窗,确认离开吗,确认将保存为草稿;利用 H5的 pushstate(个人理解为增加页面栈)特性与onpopup事件

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!