应组合使用 type 和 inputmode 控制软键盘类型,如 type="text" + inputmode="numeric";用 oninput 实时过滤非法字符,配合 onpaste 阻止粘贴绕过校验,并注意 maxlength 的 UTF-16 码元限制。

用 inputmode 和 type 控制软键盘类型
移动端用户点到输入框时弹出的软键盘,实际由 type 和 inputmode 共同决定。仅设 type="number" 不保证只输数字——iOS Safari 仍可能显示完整键盘,而 Android Chrome 可能只显示数字键但允许粘贴字母。更可靠的做法是组合使用:type="text" + inputmode="numeric"(纯数字)、inputmode="decimal"(带小数点)、inputmode="tel"(电话场景,含 *# 键)。注意 inputmode 是 HTML5 属性,IE 完全不支持,现代浏览器基本可用。
用 pattern 和 oninput 实时过滤非法字符
pattern 只在表单提交时校验,无法阻止用户输入非法内容;真正拦截得靠 JavaScript 的 oninput 事件。常见错误是监听 onkeypress 或 onkeydown,但它们无法捕获粘贴、拖入、自动填充等操作。正确做法是:
input.oninput = function() {
// 例如只允许中文、英文字母、数字和下划线
this.value = this.value.replace(/[^\u4e00-\u9fa5a-zA-Z0-9_]/g, '');
};注意两点:一是正则中不要漏掉 ^ 否则变成“保留匹配项”;二是避免在过滤后触发二次 input 事件(如 Vue/React 中直接改响应式数据可能引发循环),原生 DOM 操作无此问题。
用 maxlength 和 minlength 防止长度越界
这两个属性是纯 HTML 层限制,轻量且无需 JS。但要注意:maxlength 计的是 UTF-16 码元个数,不是字符数。比如 emoji 表情 ? 在 JS 中占 2 个码元(即 '?'.length === 2),设 maxlength="10" 实际只能输 5 个这类 emoji。若业务强依赖字符数(如微博字数),必须用 JS 计算 Array.from(value).length 并手动截断。
立即学习“前端免费学习笔记(深入)”;
禁止粘贴时绕过校验的典型处理
用户右键粘贴或 Ctrl+V 是绕过前端校验最常见方式。只监听 oninput 不够,必须同时监听 onpaste 并在事件中调用 event.preventDefault(),再手动提取文本、过滤、插入:
input.onpaste = function(e) {
e.preventDefault();
const text = (e.clipboardData || window.clipboardData).getData('text');
const filtered = text.replace(/[^0-9]/g, ''); // 示例:只留数字
document.execCommand('insertText', false, filtered);
};注意 document.execCommand 已废弃但目前仍是兼容性最好的插入方式;Chrome 98+ 支持 input.setRangeText(),但 Safari 16.4 才开始支持,生产环境建议暂不切换。另外,onpaste 里不能直接改 this.value,否则光标会跳到开头。
键盘输入限制真正的难点不在“怎么写”,而在“边界情况怎么兜住”——粘贴、IME 输入、屏幕朗读器兼容、国际化符号(如阿拉伯数字、全角字符)、以及用户故意禁用 JS 后的降级体验。别指望一个属性或一行正则解决所有问题。



















