使用是唯一能获取原生能力的方式;必须通过customelements.define("my-renderer", myrenderer, { extends: "canvas" })注册,且is值须严格匹配,super()必须在构造函数首行调用,is属性不可运行时修改。

直接用 <canvas is="my-renderer"></canvas> 是唯一能拿到 width、getContext() 等原生能力的方式;写 <my-renderer></my-renderer> 或加 data-is 都无效,元素会变成 HTMLUnknownElement,所有内置属性读出来都是 undefined。
is 属性必须配合原生标签和 extends 配置
浏览器只在解析原生标签(如 <canvas></canvas>、<button></button>)时,才可能走定制化内置元素逻辑。但前提是:
-
customElements.define("my-renderer", MyRenderer, { extends: "canvas" })中的extends选项不能省,漏掉就完全不升级 -
is的值("my-renderer")必须和define()第一个参数严格一致,大小写、连字符都不能错 - 支持的原生标签有限:目前只有
<button></button>、<input>、<canvas></canvas>、<table>、<code><p></p>等约 20 个,<div>、<code><span></span>不在列表里,加is会被静默忽略constructor 里 super() 是硬性要求,不是可选
继承
HTMLCanvasElement或HTMLButtonElement时,constructor第一行必须是super()。它负责绑定底层 DOM 对象状态,比如初始化this.width、this.value、表单关联等。漏掉或延迟调用会导致:
-
this.width始终为0,即使 HTML 里写了width="400" -
this.value读不到初始值,但getAttribute("value")还能取到字符串 - 控制台直接报错:
Failed to construct 'HTMLButtonElement': Please use the 'new' operator
注意:
super()只能在constructor里调,connectedCallback里补没用。is 属性不能运行时修改,改了也不生效
HTML 规范白纸黑字写明:
is只在元素创建时起作用。执行el.setAttribute("is", "other-button")后:-
el.constructor.name不变,仍是原来的类名 -
el instanceof HTMLButtonElement结果不变 - 所有新定义的方法、属性访问都报
undefined
真要实现“切换”行为,得靠普通属性驱动逻辑分支(比如监听
mode),或者手动销毁重建——后者代价高,且需迁移子节点、事件监听器、焦点状态等细节,容易出错。最容易被忽略的一点:你写的
is值哪怕只差一个连字符或大小写,或者注册时漏了{ extends: "canvas" },整个机制就彻底失效,而且浏览器不报错、不警告,只会安静地当它是个普通未知元素处理。 -











