ios h5中在fixed元素中的input被focus时,键盘遮挡input (van-popup、van-feild)

问题描述:

前提: 我使用的是vant组件库,其中一个页面中有一个van-popup组件,van-popup组件中又嵌套了一个van-field组件
预期结果: 当点击van-feild输入框时,键盘弹起,输入框显示在键盘上方
**实际结果:**当van-popup打开时,首次点击van-field时,键盘将van-popup遮挡,导致输入框中内容不可见。失去焦点再次点击后,van-popup被顶起。如果关闭van-popup,则会重复前面的情况

下方视频可以看看直观效果:

键盘遮挡输入框

问题分析与尝试过程:

  1. 之前遇到过类似的问题,当时是由于popup的高度导致的,修改高度就解决了 所以刚开始我也以为是高度的问题,发现调整了van-popup的高度并没有什么效果

  2. 试了安卓手机发现安卓上没有问题 由此可见是ios特有

  3. 查看是否是vant组件库的问题,看了github issues发现类似问题 但是issue只发生在了ios13上,我手中的ios16还是存在该问题,也用了上面提供的各个方法没有解决

  4. 又看到了有人用van-popup的get-container属性解决了,挂载在body或者#app下,我尝试了以后发现测试机器8plus确实ok了,但是我手里的13pro变成偶现了

  5. 焦急万分的我google一大堆,有使用scrollIntoView进行滚动的,还有监听resize手动滚动的,针对我的问题都没能解决

  6. 最后看到了参考文档1中的方式,发现无论在我的手机上还是低版本的ios上都没有再出现该问题,到这里我以为是大功告成了,认为此bug已修复

以上步骤都是2024.12.10日当天经历的,下面也就是今天2024.12.12日经历的

  1. 测试提了个bug,说输入框无法左右移动光标了,我十分天真地觉得这个光标是可以有原生方法设置的,不错确实有设置光标位置的,但是只是设置固定的位置,而我在6的方法中是阻止了默认行为,导致长按无法根据手指方向移动光标了,但是我依旧没死心啊,又问了各大ai,结果ai给的回答都是修改解决遮挡问题的办法,又回到了之前

  2. 我让ai给我分析为什么我使用的办法会让光标无法移动,它说因为阻止了默认行为,我有说我只有第一次这样,能不能在这个方法的基础上得到解决,它终于给出了一个用的上的方式,那就是只有在首次点击的时候才阻止默认行为

  3. 我回想到两天前解决的时候,发现在van-popup父组件中用v-if来控制van-popup的显示时,被遮挡的概率将会大大降低,再结合今天看了很多ios处理软件盘的流程的文档后,我找到了更简单的方法,就是在父组件中就用v-if控制van-popup显示,而van-popup中控制显示的属性将一直为true,至此我得到了两种解决方式,这一种在我自己看了最简单

解决方法:

方案一: 给van-feild添加touchstart.native事件

javascript 复制代码
<template>
  <van-popup
    position="bottom"
    class="popup"
    get-container="#app"
    :value="show"
    :overlay-style="{ background: 'rgba(0,0,0,0.5)' }"
    :close-on-click-overlay="false"
  >
    <van-field ref="fieldRef" class="field" type="email" maxlength="100" clearable v-model="email" placeholder="请输入邮箱" @touchstart.native="onInputTouch"/>
  </van-popup>
</template>

<script>
import { Popup, Loading, Toast, Field } from 'vant';

export default {
  components: {
    [Popup.name]: Popup,
    [Loading.name]: Loading,
    [Field.name]: Field,
  },
  props: {
    show: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      email: '',
      isFocused: false
    }
  },
  watch: {
    show: {
      handler(val) {
        if(val && this.isFocused) {
          this.isFocused = false;
        }
      },
      immediate: true
    }
  },
  methods: {
    onInputTouch(e) {
      if (!this.isFocused) {
        e.preventDefault();
        e.target.focus();
        this.isFocused = true;
        return;
      }
      this.isFocused = true;
    }
  }
};
</script>

**方案二(最终使用):**用v-if控制van-popup的显示,van-popup本身的show属性默认设置为true

参考文档:

1.van-popup 在ios手机上被键盘遮盖问题(使用该方法解决了遮挡,但是光标无法左右移动)

  1. 不如刷新认识移动端软键盘出现带来的网页问题(详细介绍了ios软键盘引发问题的原因)

  2. 别再用不规范的方法来解决软键盘遮挡输入框问题了

  3. Keyboard Management(说明了ios webkit如何处理键盘事件和视图布局)

  4. Handling the Virtual Keyboard(详细说明了ios safari中虚拟键盘的行为)

相关推荐
贵沫末9 分钟前
React——基础
前端·react.js·前端框架
aklry21 分钟前
uniapp三步完成一维码的生成
前端·vue.js
Rubin9328 分钟前
判断元素在可视区域?用于滚动加载,数据埋点等
前端
爱学习的茄子29 分钟前
AI驱动的单词学习应用:从图片识别到语音合成的完整实现
前端·深度学习·react.js
用户38022585982429 分钟前
使用three.js实现3D地球
前端·three.js
程序无bug31 分钟前
Spring 面向切面编程AOP 详细讲解
java·前端
zhanshuo31 分钟前
鸿蒙UI开发全解:JS与Java双引擎实战指南
前端·javascript·harmonyos
撰卢1 小时前
如何提高网站加载速度速度
前端·javascript·css·html
10年前端老司机1 小时前
在React项目中如何封装一个可扩展,复用性强的组件
前端·javascript·react.js
Struggler2811 小时前
解决setTimeout/setInterval计时不准确问题的方案
前端