
pattern 属性本身不触发实时反馈
pattern 是 <input> 的原生 HTML5 属性,只在表单提交时参与验证(或调用 checkValidity() 时),**不会监听输入过程、不触发 input 或 keyup 事件、也不自动添加 CSS 类或修改样式**。指望它“自动变红/变绿”是常见误解。
要实现编辑器中的实时视觉反馈,必须手动监听输入并执行正则匹配,再基于结果更新 UI 状态。浏览器不会替你做这层桥接。
用 input 事件 + test() 实现基础实时校验
核心思路:监听 input 事件,取当前 value,用 RegExp.prototype.test() 判断是否匹配,然后切换一个 CSS 类(比如 is-valid / is-invalid)。
- 务必使用
input事件(不是change),它在每次输入、粘贴、删除时都触发 - 正则需注意全局标志
g——test()在带g时会维护lastIndex,导致偶发错判;建议显式创建无g的正则,或每次用new RegExp(patternStr) - 若正则来自用户输入(如编辑器配置项),需用
try/catch包裹new RegExp(),避免语法错误崩掉脚本
const input = document.querySelector('input[data-pattern]');
const patternStr = input.dataset.pattern; // 例如 "^\d{3}-\d{2}-\d{4}$"
input.addEventListener('input', () => {
let isValid = false;
try {
const re = new RegExp(patternStr);
isValid = re.test(input.value);
} catch (e) {
// 正则语法错误,可标记为 invalid 或忽略
}
input.classList.toggle('is-valid', isValid && input.value !== '');
input.classList.toggle('is-invalid', !isValid && input.value !== '');
});
textarea 和 contenteditable 元素不能直接用 pattern
pattern 属性**仅对 <input> 有效**,<textarea> 和 contenteditable 元素不支持该属性。强行写上毫无作用。
立即学习“前端免费学习笔记(深入)”;
如果你的“实时编辑器”是基于 textarea 或 div[contenteditable],必须完全放弃 pattern,改用纯 JS 方案:
- 监听
input事件(textarea支持;contenteditable需监听input+compositionend防止中文输入中断) - 获取内容用
el.value(textarea)或el.innerText/el.textContent(contenteditable) - 匹配逻辑与上一节一致,但需额外处理空格、换行等边界情况
高亮匹配位置需要更精细的正则操作
如果不仅要判断“整体是否匹配”,还要像代码编辑器那样高亮子串(例如标出邮箱中的 @ 域名部分),就不能只用 test() —— 得用 exec() 或 matchAll() 提取匹配位置。
注意点:
-
matchAll()返回迭代器,需转成数组才能遍历;IE 不支持,需降级用exec()循环 - 正则需加
g标志才能多次匹配;但此时不能再和test()混用(lastIndex冲突) - 高亮 DOM 操作建议用
Range+document.execCommand()(已废弃但兼容性好)或更现代的highlightAPI(目前仅 Chrome 支持)
简单文本内高亮匹配片段,最稳做法仍是生成带 <mark> 的 HTML 字符串并设为 innerHTML(注意 XSS 过滤)。
真正难的不是写对正则,而是让反馈时机准、不卡顿、不误判中文输入法、不污染 undo 栈——这些细节比 pattern 属性本身重要得多。



















