html手机号输入框,手机号输入框自动格式化为344

写在前面

相信大家已经看过某些手机号的输入框在输入的时候,手机号是3 4 4格式,即 输入一个手机号时,会隔成 159 8888 3333 这样的输入框。笔者也实现了一个这样的组件,这个组件的特点是: 组件表现上在输入时会自动隔断成 3 4 4 格式,且只能输入数字

实现原理

基础分析

一开始看到这个需求,我一看,输入的时候劫持一下onChange,格式化一下就好了嘛,啪的一下,很快啊,代码就写好了。上来就是一个正则的捕获括号,一个字符串replace函数哈。

value = value.replace(/(\d{3})(\d{4})/, '$1 $2 ') // 15988883333 => 159 8888 3333

但是产品说你这个没用,我说我这个有用。说着就边输入,边说你这个输入的时候格式化的不对。好吧,我大意了,没有考虑仔细 。但是一想,可以更新一下,对不同长度的字符串适用不同的正则。

const getFormatPhone = (phone: string) => {

const purePhone = phone.replace(/\D/g, '');

const { length } = purePhone;

if (length <= 3) {

return purePhone;

} else if (length <= 7) {

return purePhone.replace(/(\d{3})(\d{0,4})/, '$1 $2');

} else {

return purePhone.replace(/(\d{3})(\d{4})/, '$1 $2 ');

}

};

代码跑起来,看起来很完美。但是怎么删除的时候删不动,细想,原来是在删除最后一个空格时,代码又给我自动格式化出了一个空格。我又大意了。

我刚在想怎么解决,又发现,在字符串中间输入或删除的时候,光标总是跑到最后面去了。

不对劲哈,这个需求不讲码德,来骗,来偷袭,我2岁的前端仔。能骗我两次,骗不了第三次。

仔细分析

认真分析这个需求,发现这个是有多种交互场景的,包括,普通输入,普通删除,字符串中间进行输入或删除,在不同位置下黏贴或者删除多个字符串。总的来说包括三个需要思考的。

任何输入的字符串都格式为正确的格式。

删除的时候如果是删除空格,需要再往前删除一位。

计算好光标的位置。

正确的格式化

这个用上述的getFormatPhone函数处理即可。

删除空格多删除一位

这里就涉及到一个概念,删除的位置。这里可以引入一个属性,selectionStart。在mdn中,是这样解释的

返回/ 设置 the beginning index of the selected text. When nothing is selected, this returns the position of the text input cursor (caret) inside of the `` element.(https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLInputElement)

所以可以利用这个属性来获取用户操作后光标所在的位置,从而来获得光标输入前的位置,从而来判断是否需要多删除一位

矫正光标的位置

光标的位置,这个有点难搞哦。用户有不同的操作模式,这里枚举如下:

单纯输入

单纯删除

在字符串中间开始输入

在字符串中间开始删除,包括在空格前删除

在字符串不同位置复制多个字符

在字符串不同位置剪切(即删除)多个字符

在不同的用户操作模式后都应该重新计算,

笔者总结计算公式为 光标最后的位置 = 光标原本的位置 + 纯粹增删的数字数量 - 差异的空格数量

其中差异的空格数量,是由旧的值中的空格数量 - 新的值中的空格数量。值得注意的是,这里空格数量,算的不是全部字符串中的数量,而是截止到某个位置的空格的数量,其中,旧的值应该截止到光标输入前的位置,新的值应该截止到光标输入后的位置。

这个公式理解起来就是,原本光标在N位置,由于输入了多个字符,所以应该向前向后移动,但此时由于空格,需要计算下由于空格导致的光标位置的差异。

关于删除空格时,多删除一位还是直接光标前移

可能有的人认为在删除空格时,应该自动将光标位置前进一格,而不是直接多删除一位。关于这个交互,笔者从自身用户角度出发,会认为一个删除行为就是想删除一个具体的数字,而不是单纯的前进。所以这里的交互差异暂不做具体纠葛,暂以目前的交互为准。

关于通用格式化

有人可能会说,你这能不能更通用一点,例如格式化为444。关于这个,组件想做到是可以的。可以修改一下props,传入一个所需要的格式数组,如[444],然后修改格式化的函数,将其的不同边界条件修改成传入的变量。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当测试手机号输入框时,以下是一些可能的测试用例: 1. 正常输入手机号码:输入一个有效的手机号码,例如"13888888888",确保能够正确地接受并显示输入的手机号码。 2. 空输入:不输入任何内容,直接提交或离开输入框,确保能够检测到空输入,并给出相应的提示或错误信息。 3. 非法字符输入:输入非数字字符(如字母、特殊符号等),例如"abcde",确保能够检测到非法字符,并给出相应的提示或错误信息。 4. 长度限制:输入超过手机号码长度限制的数字,例如"138888888888",确保能够检测到并截断或给出相应的提示或错误信息。 5. 类型限制:尝试在手机号输入框中输入其他类型的内容,如文本、日期等,确保能够检测到并给出相应的提示或错误信息。 6. 前导零处理:测试在手机号输入框中输入带有前导零的号码,例如"01388888888",确保能够正确地接受并显示输入的手机号码。 7. 格式校验:测试在手机号输入框中输入格式不正确的手机号码,例如"13888888"(缺少部分数字)或"1388a88888"(包含非数字字符),确保能够检测到并给出相应的提示或错误信息。 8. 边界值测试:测试输入边界值情况,例如输入最小的合法手机号码(如"10000000000")和最大的合法手机号码(如"19999999999"),确保能够正确处理。 9. 重复输入:测试重复输入相同的手机号码,确保能够正确处理,并避免重复提交或显示重复信息。 10. 效能测试:测试在手机号输入框中输入大量数据时的性能和响应时间,确保系统能够处理大量输入并保持稳定性。 以上是一些常见的手机号输入框测试用例,根据具体的业务需求和系统特点,还可以进一步补充和细化测试用例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值