定义自定义元素
使用 customElements API 注册元素。
定义自定义元素 是 CoddyKit 上的免费 JavaScript Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 JavaScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 JavaScript Academy 课程共包含 4 节课。
什么是自定义元素
自定义元素让您可以定义由 JavaScript 类支持的自定义 HTML 标签。您无需将许多 div 拼凑在一起,而是可以创建类似 <user-card> 的可复用、自包含组件。
- 它们属于 Web 组件标准。
- 它们可以原生运行在浏览器中,无需框架。
- 自定义元素名称必须包含连字符(例如
my-button)。
customElements 注册表
浏览器通过 window.customElements 提供一个全局注册表。调用 customElements.define(name, constructor) 即可注册新标签。
定义完成后,文档中所有匹配的标签都会升级为您所定义类的实例。
// Register a tag named 'hello-world'
customElements.define('hello-world', HelloWorld);
// After this, every <hello-world> in the page
// becomes an instance of the HelloWorld class.扩展 HTMLElement
自定义元素是一个 extends HTMLElement 的类。基类会为您的元素提供所有标准 DOM 功能(属性、事件和样式)。
在构造函数中始终先调用 super(),以确保元素得到正确初始化。
class HelloWorld extends HTMLElement {
constructor() {
super(); // required, sets up the element
}
}
customElements.define('hello-world', HelloWorld);渲染内容
在元素内部,您可以设置 this.innerHTML,或使用 DOM 方法构建内容。一种常见模式是在元素连接到页面时进行渲染。
class HelloWorld extends HTMLElement {
connectedCallback() {
this.innerHTML = '<p>Hello from a custom element!</p>';
}
}
customElements.define('hello-world', HelloWorld);在 HTML 中使用元素
注册完成后,像使用任何内置元素一样使用您的标签。您可以直接将它放入标记中,也可以使用 document.createElement 创建它。
// In HTML:
// <hello-world></hello-world>
// Or in JavaScript:
const el = document.createElement('hello-world');
document.body.appendChild(el);构造函数的规则
创建实例时会运行构造函数。这里有一些严格的规则:
- 先调用
super()。 - 不要在这里检查或添加属性和子元素。
- 将 DOM 操作推迟到
connectedCallback中。
构造函数只能用于设置初始状态和事件监听器。
class CounterButton extends HTMLElement {
constructor() {
super();
this.count = 0; // safe: just internal state
}
}
customElements.define('counter-button', CounterButton);添加行为
由于您的元素是真实的 DOM 节点,因此您可以为它附加事件监听器,并根据交互更新其内容。
class CounterButton extends HTMLElement {
constructor() {
super();
this.count = 0;
}
connectedCallback() {
this.textContent = 'Clicked 0 times';
this.addEventListener('click', () => {
this.count++;
this.textContent = 'Clicked ' + this.count + ' times';
});
}
}
customElements.define('counter-button', CounterButton);连字符要求
自定义元素名称必须包含连字符。这可以确保它们不会与当前或未来的内置 HTML 元素冲突。
my-widget有效。mywidget无效,会抛出错误。- 名称不区分大小写,但应使用小写书写。
// Valid:
customElements.define('app-header', AppHeader);
// Invalid - throws SyntaxError (no hyphen):
// customElements.define('appheader', AppHeader);whenDefined 和 get
两个实用的注册表方法:
customElements.get(name)返回构造函数;如果尚未注册,则返回undefined。customElements.whenDefined(name)返回一个 Promise,在元素定义完成后解析。
customElements.whenDefined('hello-world').then(() => {
console.log('hello-world is ready to use');
});
const Ctor = customElements.get('hello-world');只能定义一次
每个名称只能注册一次。使用已占用的名称调用 define 会抛出错误。请在共享模块中防止重复注册。
if (!customElements.get('hello-world')) {
customElements.define('hello-world', HelloWorld);
}自定义元素为何重要
自定义元素为您提供与框架无关、封装且可复用的用户界面。它们可以:
- 在任何技术栈中规范组件复用。
- 与浏览器自身的生命周期集成。
- 自然地与阴影 DOM 和模板配合使用(稍后介绍)。
快速检查
检验您对定义自定义元素的理解。
回顾
您已经学会了如何定义自定义元素:
customElements.define(name, class)会注册一个标签。- 该类
extends HTMLElement,并首先调用super()。 - 名称必须包含连字符。
- 请在
connectedCallback中渲染内容,而不是在构造函数中渲染。 get和whenDefined可以帮助您检查注册状态。
接下来,我们将探索自定义元素的完整生命周期。
常见问题解答
「定义自定义元素」课时是免费的吗?
是的 — 「定义自定义元素」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 JavaScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 JavaScript Academy 课程共包含 4 节课。
「定义自定义元素」这节课中我会学到什么?
使用 customElements API 注册元素。 你通过在浏览器中直接运行的动手代码来练习 JavaScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 JavaScript Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 JavaScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「定义自定义元素」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 JavaScript Academy 课中编写并运行代码吗?
能。每节 JavaScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 定义自定义元素
- 生命周期回调
- Shadow DOM 与封装
- 模板与插槽