is属性不参与表单校验,仅决定元素构造类和原型链;正确注册并继承HTMLInputElement后,方可调用checkValidity()、reportValidity()等原生校验API。

is 属性在原生表单校验中完全不参与、不触发、不改变任何校验行为——它和 setCustomValidity()、reportValidity()、checkValidity() 等表单验证 API 没有直接关联,也不能让自定义元素自动获得表单提交、form 关联或 validity 对象。
如果你正试图用 <input is="my-input"> 来“增强”原生校验逻辑,那大概率走错了方向:浏览器不会因为加了 is 就帮你接管 required、pattern 或服务端异步校验流程。
is 属性根本不影响表单校验逻辑
-
is只决定元素的构造类和原型链(比如是否是HTMLInputElement实例),不注入任何校验钩子 - 即使你注册了
customElements.define("my-input", MyInput, { extends: "input" }),且写了<input is="my-input" required>:-
required、type="email"、pattern这些仍由浏览器原生处理 -
input.validity.valid、input.checkValidity()的行为和普通<input>完全一致 - 你写的
MyInput类里不会自动收到校验失败回调,也不会被调用setCustomValidity()
-
常见错误现象:
- 自定义类里监听
input事件并调this.setCustomValidity("错"),但submit时没拦截、没提示 - 表单提交成功了,但后端返回“用户名已存在”,前端却没显示错误 —— 因为
setCustomValidity()调得太晚,或没配合reportValidity() -
<input is="my-input">在<form></form>内,但form.elements里取不到该字段,或form.reportValidity()忽略它 —— 原因通常是注册漏了{ extends: "input" },导致它实际是HTMLUnknownElement
想扩展表单校验?得靠 setCustomValidity() + 手动控制流
is 属性本身不提供校验能力,但如果你用它创建了一个真正继承 HTMLInputElement 的实例(即注册正确、写法正确),那你就可以在该实例内部安全调用原生校验方法:
立即学习“前端免费学习笔记(深入)”;
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
-
this.checkValidity()返回布尔值 -
this.reportValidity()触发 UI 错误提示(含气泡) -
this.setCustomValidity("...")设置/清空自定义错误文案
关键操作必须手动组织:
- 在
submit事件里e.preventDefault() - 先调
input.reportValidity()做本地校验(required、pattern等) - 本地通过后发请求;失败则
input.setCustomValidity("用户名已被占用")+input.reportValidity() -
每次异步开始前必须先
input.setCustomValidity(""),否则旧错误残留
示例片段:
const input = document.querySelector('input[is="async-username"]');
input.form.addEventListener('submit', e => {
e.preventDefault();
if (!input.reportValidity()) return;
<p>input.setCustomValidity(''); // 清空旧状态
fetch('/api/check?name=' + input.value)
.then(r => r.json())
.then(data => {
if (data.taken) {
input.setCustomValidity('该用户名已被注册');
input.reportValidity();
} else {
input.form.submit(); // 手动提交
}
});
});</p>为什么 <input is="my-input"> 有时校验失效?
根本原因不是 is 本身有问题,而是注册或使用环节断链:
- 注册时漏掉
{ extends: "input" }→ 元素仍是HTMLInputElement,不走你的类,constructor都没执行 -
MyInput类没继承HTMLInputElement,只继承HTMLElement→ 即使写了is,也升级失败 -
super()没在constructor第一行调用 →this.value、this.validity全部为undefined,setCustomValidity()报错或静默失败 - HTML 中用了
<my-input></my-input>而非<input is="my-input">→ 浏览器当它是自主元素,和表单系统完全脱钩
最常被忽略的一点:is 值大小写、连字符、空格必须和 customElements.define() 第一个参数逐字符一致。注册了 "async-username",就不能写 is="AsyncUsername" 或 is="async_username" —— 浏览器不报错,但整个机制静默失效。


















