uniapp - 键盘上推 踩坑

一、前言

这是一个很常见很普遍的功能了,在输入框获取到焦点后,弹出键盘,把页面上推。在 uni-app 关于 textarea 的介绍中有相关配置。

adjust-position,默认为 true 。键盘弹起时,是否自动上推页面

那从哪里开始推,推哪个地方,我的整个【输入框-键盘】是一个组件,当然是希望将整个组件上推的。查阅文档,有个参数来处理这个 推的 的目标点。

cursor-spacing,默认为 0 。指定光标与键盘的距离,单位 px 。取 textarea 距离底部的距离和 cursor-spacing 指定的距离的最小值作为光标与键盘的距离

也就是说默认情况下,会从 输入框的底部 开始推,但组件的设计:

很明显,不能从 输入框的底部开始推,应该从整个组件的底部开始推。从这个属性的介绍来说,目前就是从输入框的底部开始推。

二、 缺陷初显

通过这个属性的介绍,可以设置 cursor-spacing 的大小,取 输入框下面功能区的高度的值。这时,聚焦输入框,键盘能推整个输入框组件向上。

!!!bug。正如属性的介绍,是光标与键盘的距离,假设值为 100 ,则光标与键盘的距离是 100。我也是忽略了一个一个问题,正常打字的时候,光标始终是在最后一行,也是紧贴这输入框底部。

这时,textarea 距离底部的距离 和 cursor-spacing 的值是相等的,因此所谓最小值,其实都相等。

当输入框内容多行时,移动光标到非最后一行处,键盘就会上移,覆盖部分组件 。其实,这个很容易理解,用前面属性的介绍来说,是对比 textarea 距离底部的距离 和 cursor-spacing 的值,取最小值。当移动光标时,textarea 距离底部的距离已经小于 cursor-spacing的值,因此存在这个缺陷。

三、方案

使用以上两个属性来实现 上推 功能,在我的实践看来,无法实现。后面,从 定位 得到了灵感。在做底部按钮或者顶部nav 的时候,存在 绝对定位和固定定位,那往往是需要给元素一个 padding ,把元素挤出来。调试的时候发现了,当键盘弹出的时候,类似固定定位,这时候只要给组件外层元素添加一个 padding-bottom,值为键盘的高度。

1. 获取键盘高度

html 复制代码
    <textarea
              class="input-inner"
              v-model="value"
              :auto-height="autoHeight"
              placeholder="请输入发送内容"
              placeholder-style="color:#B3B3B3"
              confirm-type="send"
              :adjust-position="false"
              :show-confirm-bar="false"
              :disable-default-padding="true"
              @confirm="handleSend"
              @keyboardheightchange="handleKeyboardheightchange"
            />

绑定 keyboardheightchange 获取键盘高度。

js 复制代码
    handleKeyboardheightchange(e) {
      this.keyboardHeight = e.detail.height;
    },

2. 设置外层元素边距

根据键盘高度动态设置外层元素的边距。

html 复制代码
 <view class="input" :style="style">
 // 已有代码
 </view>
vue 复制代码
  computed: {
    style() {
      const flag = this.keyboardHeight > 0;
      const height = flag
        ? `calc(5rpx + ${this.keyboardHeight}px)`
        : `calc(10rpx + env(safe-area-inset-bottom))`;
      return `padding-bottom: ${height}; `;
    },
  },

四、总结

记住!!! 像这种多行文本框,需要上推键盘的,就用 方案三 这种方式。

相关推荐
风舞15 小时前
一文搞定JavaScript Reflect最佳实践
前端·javascript
小高00715 小时前
⚡CSS 原子化:30 行代码让样式复用率飙升 300%
前端·面试
三十_15 小时前
NestJS 开发必备:HTTP 接口传参的 5 种方式总结与实战
前端·后端·nestjs
coding随想15 小时前
揭秘常见的摇一摇抽奖功能:深度解析HTML5 devicemotion事件的原理与实战技巧!
前端
程序员的世界你不懂15 小时前
【Flask】测试平台开发,应用管理模块实现-第十一篇
vue.js·elementui·flask
Cache技术分享15 小时前
178. Java 包
前端·javascript·后端
小小小怪兽15 小时前
基于人工智能的表单开发-另一种角度的低代码
前端
龙在天16 小时前
首屏优化
前端
小鱼儿亮亮16 小时前
Vue.js 父子组件通信的十种方式
前端·vue.js
疯狂踩坑人16 小时前
useRequest - vue3版本
vue.js