可在input事件中实时格式化手机号为xxx-xxxx-xxxx,先清除非数字字符并截取前11位,再按规则插入横杠,同时通过记录和调整selectionstart/end来同步光标位置,避免跳位或重复添加。

可以在输入框的 input 事件中监听值的变化,通过正则和字符串操作,在第3位和第7位后插入横杠(-),同时控制光标位置防止跳位。关键点是:格式化值、同步光标、避免重复添加。
监听输入并格式化手机号
使用 input 事件实时处理用户输入,提取纯数字,再按 XXX-XXXX-XXXX 格式拼接:
- 用
value.replace(/\D/g, '')去掉所有非数字字符 - 截取前11位(国内手机号长度)
- 按规则插入横杠:第3位后、第7位后,即
str.slice(0,3) + '-' + str.slice(3,7) + '-' + str.slice(7)
保持光标在合理位置
直接赋值 input.value 会导致光标跳到末尾。需手动保存并恢复光标位置:
- 在格式化前记录
input.selectionStart - 计算格式化后光标应处的位置(例如原光标在第4位,加了1个横杠后应变为第5位)
- 设置完新值后,用
setSelectionRange恢复光标
防止横杠被删除或重复插入
用户可能手动删横杠或粘贴带横杠的内容,需统一清洗再格式化:
- 无论输入来源(键盘、粘贴、剪切),都先
.replace(/-/g, '')清除已有横杠 - 再走纯数字提取 → 截断 → 插入横杠流程
- 对退格键等特殊操作无需单独判断,因
input事件已覆盖所有值变更场景
简单可运行示例
HTML 中定义输入框,JS 绑定逻辑(含光标修复):
<input type="tel" id="phone" placeholder="请输入手机号"><script>
const input = document.getElementById('phone');
input.addEventListener('input', function () {
const raw = this.value.replace(/\D/g, '').slice(0, 11);
let formatted = '';
if (raw.length > 3) {
formatted = raw.slice(0, 3) + '-';
if (raw.length > 7) {
formatted += raw.slice(3, 7) + '-' + raw.slice(7);
} else {
formatted += raw.slice(3);
}
} else {
formatted = raw;
}
<p>const oldLen = this.value.length;
const newLen = formatted.length;
const start = this.selectionStart;
const end = this.selectionEnd;<p>this.value = formatted;<p>// 粗略调整光标:假设只在末尾增删,偏移量 = 新旧长度差
// 更精确做法需结合原光标位置与横杠插入点判断
const diff = newLen - oldLen;
this.setSelectionRange(start + diff, end + diff);
});
</script>











