阅读 161

Web Components 相关技术基础介绍 (下)

Web Components 相关技术基础介绍

1. Custome elements

这项技术还是比较容易理解的;顾名思义,自定义标签就是 HTML 元素,比如 <div><section><article>, 但是我们可以通过浏览器 API 自己命名。自定义元素就像那些标准的 HTML 元素一样(名字在尖括号中) ,只不过它们总是有一个破折号,比如 <news-slider><bacon-cheeseburger > 。这么做的目的是为了防止与原生内置标签产生冲突。

自定义元素包含自己的语义、行为、标记,可以在框架和浏览器之间共享。

class MyComponent extends HTMLElement {
  connectedCallback() {
    this.innerHTML = `<h1>Hello world</h1>`
  }
}

customElements.define('my-component', MyComponent)
复制代码

image image

在这个例子中,我们定义了我们自己的 HTML 元素 <my-component> 。诚然,它并没有做很多工作,但这是定制元素的基本构建块。所有自定义元素都必须以某种方式扩展 HTMLElement,才能在浏览器中注册并使用。

在编码中,没有依赖任何第三方框架,浏览器厂商在升级时,也在致力于规范的向下兼容,几乎保证了按照规范编写的组件不会受到破坏API变化的影响。更重要的是,这些组件通常可以用于当今最流行的框架,包括 Angular、 React、 Vue 和其他框架。更多

2. Shadow Dom

Shadow DOMDOM 的封装版本。这使得开发者可以有效地将 DOM 片段彼此隔离开来,包括任何可以用作 CSS 选择器的内容以及与它们相关的样式。通常,文档作用域内的任何内容都称为 light DOM,而Shadow Root中的任何内容都称为Shadow DOM

image

当使用 light DOM 时,可以使用 document.querySelector('selector')选择元素,或者使用 element.querySelector('selector') 选择任何元素的子元素;

同样,可以通过调用 shadowRoot.querySelector 来选择阴影根的子元素,而 shadowRoot 是对文档片段的引用; 区别在于阴影根的子元素不能从 light DOM 中选择。例如,如果我们有一个包含 <button> 的阴影根,调用 shadowRoot.querySelector('button') 将返回我们的按钮,但是不能document's查询选择器获取该元素,因为它属于不同的 DocumentOrShadowRoot 实例。

在这方面,shadow DOM 的工作方式有点像 <iframe> ,其中shadow DOM中的内容与document的其余部分隔离开来; 然而,当我们创建 shadow root 时,我们仍然可以完全控制页面的这一部分,但是范围仅限于上下文。这就是我们所说的封装

如果您曾经编写过重用相同 id 的组件,或者依赖于 CSS-in-JS 工具或 CSS 命名策略(比如 BEM) ,那么 shadow DOM 有可能改善您的开发人员体验。

想象一下这样的场景:

<div>
  <div id="example">
    <!-- Pseudo-code used to designate a shadow root -->
    <#shadow-root>
      <style>
      button {
        background: tomato;
        color: white;
      }
      </style>
      <button id="button">This will use the CSS background tomato</button>
    </#shadow-root>
  </div>
  <button id="button">Not tomato</button>
</div>

复制代码

除了 <#shadow-root> 的伪代码(这里使用它来划分 shadow DOM 的边界)之外,其他的 HTML 是完全有效的。为了在上面的节点上附加一个shadow root,我们可以运行下面的代码:

const shadowRoot = document.getElementById('example').attachShadow({ mode: 'open' })
shadowRoot.innerHTML = `<style>
button {
  color: tomato;
}
</style>
<button id="button">
    This will use the CSS color tomato <slot></slot>
</button>`
复制代码

通过使用 <slot> 元素,影子根还可以包含其他外部节点内容。使用插槽会将用户内容从外部节点 放到阴影根元素的指定位置。

image image

3.template

命名恰当的 HTML <template> 元素允许我们在普通 HTML 流中重用的代码模板,这些模板不会立即显示,但可以在需要的时候使用。

<template id="book-template">
  <li><span class="title"></span> &mdash; <span class="author"></span></li>
</template>

<ul id="books"></ul>
复制代码

上面的例子不会渲染任何内容,直到脚本使用了模板,实例化了代码并告诉浏览器该如何处理它。

const fragment = document.getElementById('book-template')
const books = [
  { title: 'The Great Gatsby', author: 'F. Scott Fitzgerald' },
  { title: 'A Farewell to Arms', author: 'Ernest Hemingway' },
  { title: 'Catch 22', author: 'Joseph Heller' },
]

books.forEach((book) => {
  // Create an instance of the template content
  const instance = document.importNode(fragment.content, true)
  // Add relevant content to the template
  instance.querySelector('.title').innerHTML = book.title
  instance.querySelector('.author').innerHTML = book.author
  // Append the instance ot the DOM
  document.getElementById('books').appendChild(instance)
})
复制代码

表面上,使用利用模板 API 的服务的用户可以编写任何形状或结构的模板,这些模板可以在以后创建。网站上的另一个页面可能使用相同的服务,但是模板的结构是这样的:

<template id="book-template">
  <li><span class="author"></span>'s classic novel <span class="title"></span></li>
</template>

<ul id="books"></ul>
复制代码

image image image

Web Components 规范是一组底层 api,它们将随着开发人员的需求而不断发展和演进。

在下一篇文章中,我们将更深入地了解 HTML 模板部分。然后,我们将继续讨论自定义元素和影子 DOM。最后,我们将着眼于更高层次的工具,并将其与当今流行的库和框架结合起来,从而总结全部内容。

文章分类
前端