基于libphonenumber-js实现手机号输入框填满后禁止输入
问题:使用libphonenumber-js的AsYouType格式化手机号时限制输入长度
我正在用libphonenumber-js库的AsYouType组件对手机号输入框做格式化,比如输入xxxxxxxxxxx会被格式化为xxxx xxx xx xx。现在需要实现手机号达到对应国家的最大长度后禁止用户继续输入的功能(比如示例中号码纯数字长度为9位时,不能再输入更多字符),但官方文档里没提这个功能。
当前格式化输入的代码如下:
telInput.addEventListener('input', function () { const formatter = new AsYouType(isoCode2) telInput.value = formatter.input(telInput.value) })
注:手机号的最大允许长度会根据另一个下拉选择框的选择(切换国家)而变化。
请问该怎么实现这个需求?
解决方案
要实现这个功能,核心是先获取当前国家对应的手机号最大纯数字长度,再在输入事件中对纯数字内容做截断处理,最后重新格式化。具体步骤和代码如下:
1. 维护/获取当前国家的最大手机号长度
可以通过两种方式获取:
- 方式一:利用libphonenumber-js内置方法:通过
getExampleNumber获取对应国家的示例号码,提取其纯数字长度作为最大允许长度。 - 方式二:手动维护映射表:如果需要更精准的控制,直接创建一个国家代码与最大长度的映射对象。
2. 监听国家下拉框,更新最大长度
当下拉框切换国家时,同步更新全局的最大长度变量:
// 全局变量存储当前国家的最大手机号纯数字长度 let maxPhoneLength = 9; // 默认初始值 const countrySelect = document.getElementById('your-country-select-id'); // 监听国家选择变化 countrySelect.addEventListener('change', function() { const currentIsoCode = this.value; // 方式一:用示例号码获取长度 const exampleNum = getExampleNumber(currentIsoCode).nationalNumber; maxPhoneLength = exampleNum.length; // 方式二:手动映射表(按需替换) // const countryLengthMap = { // 'FR': 9, // 'CN': 11, // 'US': 10 // }; // maxPhoneLength = countryLengthMap[currentIsoCode] || 9; });
3. 修改输入框事件处理逻辑
在input事件中先提取纯数字内容,判断长度是否超限,截断后再重新格式化:
const telInput = document.getElementById('your-tel-input-id'); telInput.addEventListener('input', function () { const currentIsoCode = countrySelect.value; const formatter = new AsYouType(currentIsoCode); // 提取输入中的所有纯数字字符 let rawDigits = this.value.replace(/\D/g, ''); // 若超过最大长度,截断到允许的最大值 if (rawDigits.length > maxPhoneLength) { rawDigits = rawDigits.slice(0, maxPhoneLength); } // 逐个输入数字到AsYouType中,确保格式化正确 let formattedValue = ''; for (const digit of rawDigits) { formattedValue = formatter.input(digit); } this.value = formattedValue; });
补充说明
- 必须基于纯数字长度判断,因为格式化后的字符串包含空格等分隔符,不能直接用输入框的value长度判断。
- 逐个输入数字到AsYouType中,比直接传入截断后的字符串更可靠,能保证格式化结果符合预期。
- 如果需要更精准的长度校验,可以解析libphonenumber-js的metadata(通过
getMetadataForCountry方法),获取号码的长度规则范围,不过对于大多数业务场景,示例号码长度已经足够。
内容的提问来源于stack exchange,提问作者Fettah_Aud
相关产品推荐
相关产品推荐

