H5+Vue2: input(number/tel)唤起数字键盘,踩坑日记

h5页面做一个搜索功能,且只支持数字[0-9]输入。本来觉得so easy,结果笑容逐渐消失。

一、input type=number

<input type="number" v-model="val">

问题接踵而来:

1、maxlength属性失效,需要针对输入 @input 处理

<input type="number" v-model="val" @input="inputVal">

// js
inputVal (e) {
  this.val = e.target.value.slice(0, this.maxlength)
}

2、+-.eE 这几个和浮点数相关的值,可以输入(其中e/E是科学计数法的关键字,1e2 = 1 * 10 ^ 2。这里的问题是多方面的:

  • 文本框展示的值,与实际的value值差异明显。
  • 输入后可能无法删除。
  • 按我们的搜索需求,这几个值不应该支持输入

举例:

1)小数点。如输入13.14时,结果如下图。其中:13和13.,value都是13。

 2)+-eE。如输入+-e,结果如下图。value是空字符串('')。且无法清空。

so,针对这几个特殊字符,其中的一个思路就是限制输入。

1)监听keypress/keydown事件,不满足输入时,阻止事件的默认行为。

<input type="number" v-model="val" @input="inputVal" @keypress="keypressVal">

keypressVal (e) {
  let {key} = e;
  // 方式一:
  e.returnValue = /[0-9Backspace]/.test(key)
  // 方式二:
  // if (/[^0-9Backspace]/.test(key)) {
  //   e.preventDefault()
  // }
}

在浏览器上测试,除了e,别的都输入不了(实际是输入法是英文的,除了e都输入不了;但中文输入法,这几个字符都能输入)。到Android机上测试,结果是这几个字符均可正常输入,就像这几行代码没加一样。ios已经不想测试了,心real累了。

2)input支持pattern属性,继续尝试

<input type="number" v-model="val" @input="inputVal" pattern="[0-9]*">
<input type="number" v-model="val" @input="inputVal" pattern="\d">

到Android机上测试,只是唤起了数字键盘,不耽误输入+-.eE。

至此,type=number 的方式被彻底放弃。

二:input type=tel

<input type="tel" v-model="tel" maxlength="5">

默认唤起数字键盘,支持maxlength,且支持所有的字符。类似默认唤起数字键盘 type=text 的文本框。按我们的需求,输入为非数字时,可替换为空字符。

<input type="tel" maxlength="5" @input="inputNumeric" v-model="numeric">

inputNumeric (e) {
  this.numeric = e.target.value.replace(/\D/, '')
}

 此方式基本满足需求。作为公共组件的话,还得花时间完善一下代码。

三:手写一个数字键盘

如果个人有能力,且愿意实践,手写一个数字键盘,也不失为一个方法。只是代价有点大,本人手动忽略(如果项目有特殊要求除外)。如果要站在巨人肩膀上,vant提供了数字键盘

四:成熟的组件库 Vant-Field 输入框

// Vue 2 项目,安装 Vant 2
npm i vant@latest-v2 -S

// 手动按需引入组件
import Vue from 'vue'
import { Field } from 'vant'
import 'vant/lib/field/style'
Vue.use(Field)

<!-- 允许输入正整数,调起纯数字键盘 -->
<van-field v-model="digit" type="digit"/>

亲测好用,且提供了多种类型的输入框。咳,走了那么多弯路,最后得来全不费功夫。

源码:

type="digit": <input type=tel  inputmode=numeric>,且对输入值value做了处理(过滤小数点、负号,只支持纯数字)。

还得是input type=tel,是本文二(二:input type=tel) 的高阶版。其中,inputmode并不是常用属性,需要学习,详见下文。

五:总结

h5页面做一个搜索功能,且只支持数字[0-9]输入。首先,最简单的方式是使用成熟组件库(可使用Vant 的Field 输入框)。其次是使用input type=tel,非数字的输入需处理成空字符串。最复杂的处理方式是定制一个数字键盘,甚至其中的数字可以是乱序的(某些银行app的数字键盘)。

六:补充说明

MDN inputmode:控制键盘的展示形式。可能的值:

  • none:不使用系统提供键盘。用于页面有自定义键盘的情况。
  • text:本地标准键盘。
  • numeric:数字键盘。数字键,可能还包含减号。
  • decimal:数字键盘。数字键和十进制的分隔符(.或,)。
  • tel:数字键盘。数字键、星号(*)、井号(#)。
  • search:用于搜索。回车/提交键盘可能显示成 search 或 搜索。
  • url:用于输入URLs。键盘上有 / 符号。
  • email:用于输入邮件地址。键盘上有@符号。

首先,tel、search、url、email 这四个值。

  • 需要tel键盘时,一般使用<input type="tel">,而不是inputmode=tel。
  • 需要搜索键盘时,一般使用<input type="search">,而不是inputmode=search。
  • 需要输入URLs时,一般使用<input type="url">,而不是inputmode=url。
  • 需要输入邮件地址时,一般使用<input type="email ">,而不是inputmode=email 。

其次,对于数字键盘,ios和Android,UI差异还是比较明显的。并不影响使用,注意功能的实现即可。

The end.

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值