带你深入理解 Custom Elements

前言

在现代 web 开发中,组件化已经成为了一个不可或缺的部分。我们希望能够封装一些 UI 组件,使得它们可以被重复地使用,而且我们也希望这些自定义组件能够与原生 HTML 元素一样具备类似的特性,例如可以添加事件监听器、可以添加属性等等。Custom Elements 正是为了解决这些问题而被引入到了 Web Component 中。

什么是 Custom Elements?

Custom Elements 是 Web Components 规范中的一部分,通过它我们可以轻松地创建自定义的 HTML 元素。使用 Custom Elements,我们可以创建一些封装好的组件,这些组件可以像原生元素一样参与到页面的渲染中,而且提供了一些很便利的功能和特性。

Custom Elements 主要有两种类型的元素:autonomous(独立类型) 和 customized(定制类型)。独立类型元素创建时可以不基于任何标准 DOM 元素;定制类型元素是基于现有的标准 DOM 元素扩展而来的。

下面是一个基本的 Custom Elements Demo,我们将会一步一步地讲解其中每一个部分。

在这个 Demo 中,我们创建了一个 Custom Element,它的名称叫做 hello-world,这个 Custom Element 会渲染出一句话:"Hello, World!"。我们还可以看到,跟传统的 HTML 元素一样,我们可以直接在 HTML 代码中使用 hello-world 这个元素。

接下来,我们来一步一步地讲解代码中的各个部分。

创建 Custom Elements

在 Custom Elements 中,我们通过继承 HTMLElement 类来创建自定义 HTML 元素。如下所示:

在这个例子中,我们定义了一个叫做 "HelloWorld" 的自定义元素。我们声明了一个 class,并继承自 HTMLElement 类,就像继承任何其他的 JavaScript 类一样。

在构造器函数中,我们通过 super() 调用父类的构造器函数。此时,我们刚刚创建的 custom element 就已经被初始化了。

Shadow DOM

在 Custom Elements 中使用 Shadow DOM 可以让我们在独立的 DOM 树中实现组件的封装,这可以帮助我们减少组件与其他元素之间的耦合度,从而提高代码的可维护性和可读性。

我们可以在 Custom Elements 类的构造器函数中使用 attachShadow 方法来创建 Shadow DOM。

在这个例子中,我们调用了 attachShadow 方法并传递了一个 options 对象,这个对象只有一个 mode 属性,其值可以是 open 或者 closed。如果设置为 open,那么外部代码可以访问这个 Shadow DOM,如果设置为 closed,那么外部代码将无法访问这个 Shadow DOM。

Shadow DOM 中的 HTML

在这个例子中,我们使用 innerHTML 属性来设置 Shadow DOM 中的 HTML 内容。我们将 shadowRoot 中的 HTML 设置为一个包含一行文本的 h1 标签。

注册 Custom Elements

在 Custom Elements 中,我们需要通过调用 customElements.define 方法来注册我们定义的自定义元素。

在这个例子中,我们将 "hello-world" 用作我们所创建的 Custom Element 的名称,同时定义了该元素的构造函数为 HelloWorld

总结

Custom Elements 是 Web Components 规范中的一部分,可以让我们创建自定义的 HTML 元素。使用 Custom Elements,我们可以创建一些封装好的组件,这些组件可以像原生元素一样参与到页面的渲染中,而且提供了一些很便利的功能和特性。

Custom Elements 主要有两种类型的元素:autonomous(独立类型)和 customized(定制类型)。独立类型元素创建时可以不基于任何标准 DOM 元素;定制类型元素是基于现有的标准 DOM 元素扩展而来的。

在 Custom Elements 中使用 Shadow DOM 可以让我们在独立的 DOM 树中实现组件的封装,这可以帮助我们减少组件与其他元素之间的耦合度,从而提高代码的可维护性和可读性。

最后,我们需要通过调用 customElements.define 方法来注册我们定义的自定义元素。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/653a01617d4982a6eb3b7220


纠错
反馈