如何解决输入法键盘弹出层的问题?


图片中的功能主要是输入验证码,当输入一个数字后光标会自动向下一个框移动。

使用的是跨端的框架开发的,在 web 移动端没有问题,但是在 ios 下的微信小程序,会发现当光标移动到下一个输入框时,输入法的键盘弹出层会先关闭之后再弹出。

有人建议是把 input 修改为 textarea,因为 textarea 有一个保持输入框键盘弹出层的选项,但是实际使用起来不起效果,而且发现 textarea 并不能限制输入的是数字键盘,而 input 可以。
之后我打算只用一个 input 框实现,然后使用 letter-spacing 来分隔输入的内容,而框的效果使用掩眼法实现,这个在 web 移动端也是可以的,但是放在微信小程序下 letter-spacing 失效了。
请问一下如何能解决这个在微信小程序下的兼容性问题

阅读 1.7k
2 个回答
Page({
  data: {
    value: ''
  },
  bindInput: function(e) {
    this.setData({
      value: e.detail.value
    });
    if (e.detail.value.length >= 4) {
      wx.hideKeyboard({
        success: (res) => {
          console.log(res);
        },
      });
    }
  },
  bindBlur: function(e) {
    if (this.data.value.length < 4) {
      wx.showKeyboard({
        defaultValue: this.data.value,
        maxLength: 4,
        multiple: false,
        confirmHold: true,
        confirmType: 'done',
        success: (res) => {
          console.log(res);
        },
      });
    }
  }
})

uniapp可以拿这个手机号验证输入去改

<template>
  <div class="phone-validate-input">
    <div v-for="i in prefix">{{ i }}</div>

    <div
      v-for="(i, j) in input"
      class="fake-input"
      :class="focus && j === index && 'focusing'"
      @click="onFocus(j)"
    >
      {{ i }}
    </div>

    <div v-for="i in suffix">{{ i }}</div>

    <input
      v-model="tempValue"
      class="input"
      :focus="focus"
      type="number"
      maxlength="1"
      border="none"
      @input="onInput"
      @blur="onBlur"
    />
  </div>
</template>

<script>
import wxMixin from '@/mixin/wx'

export default {
  name: 'PhoneValidateInput',

  mixins: [wxMixin],

  props: {
    // 用户输入完成后的值
    value: String,
    // 用于对比的手机号
    compare: String
  },

  data() {
    return {
      ignoreThisUpdate: false,  // 是否忽略本次update操作
      tempValue: '',

      focus: false,    // 是否聚焦
      index: -1,       // 当前输入到第几位
      input: Array(4).fill(1).map(() => ''),   // 用户需要输入的内容

      prefix: '',
      suffix: ''
    }
  },

  watch: {
    value() {
      this.update()
    },
    compare() {
      this.update()
    }
  },

  methods: {
    update() {
      const { ignoreThisUpdate, value, compare, input: inputList } = this

      if (ignoreThisUpdate) {
        this.ignoreThisUpdate = false
        return
      }

      const input = value.slice(3, 7)
      inputList.forEach((_, i) => {
        const char = input[i]
        inputList[i] = char && char !== '_' ? char : ''
      })

      this.focus = false
      this.input = inputList
      this.prefix = compare.slice(0, 3)
      this.suffix = compare.slice(7)
    },

    onFocus(i) {
      this.focus = true
      this.index = i
    },

    onInput() {
      const { index, prefix, suffix } = this

      if (index < 4) {
        this.index = index + 1
        this.input.splice(index, 1, this.tempValue)
        this.ignoreThisUpdate = true

        const payload = prefix + this.input.map(i => i || '_').join('') + suffix
        this.$emit('input', payload)

        // 最后一位输入后也隐藏
        if (index !== 3) {
          this.$nextTick(() => this.tempValue = '')
          return
        }
      }

      this.$nextTick(() => {
        this.index = -1
        this.focus = false
        this.tempValue = ''
      })
    },

    onBlur() {
      this.focus = false
    }
  },

  mounted() {
    this.update()
  }
}
</script>

<style lang="scss" scoped>
.phone-validate-input {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 44rpx;

  .fake-input {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 70rpx;
    width: 70rpx;
    border: 1px solid #707070;
    border-radius: 10rpx;
    color: #b33328;

    &.focusing::after {
      content: '|';
      height: 100%;
      color: black;
      animation: 1s cursor-flicker infinite;
    }
  }

  .input {
    height: 0 !important;
    width: 0 !important;
  }
}

@keyframes cursor-flicker {
  from {
    opacity: 0;
  }

  50% {
    opacity: 1;
  }

  100% {
    opacity: 0;
  }
}
</style>
推荐问题
logo
Microsoft
子站问答
访问
宣传栏