web components

本文详细介绍了Web Components技术,包括Custom Elements(自定义元素)、Shadow DOM和HTML模板。Custom Elements允许开发者创建带有特定行为和样式的自定义HTML标签,Shadow DOM用于封装组件样式和结构,HTML模板则提供了不立即呈现的结构。通过这三个技术,开发者可以构建可复用、可维护的网页组件。文章还讨论了自定义元素的生命周期方法、模板的使用方式,以及如何利用Shadow DOM实现样式隔离。此外,提到了一些高级工具,如lit-html和LitElement,帮助开发者更方便地创建高性能的Web Components。
摘要由CSDN通过智能技术生成

Web components 是什么?

web components 就是网页组件式开发的技术规范。

web components 由三个独立的技术组成:

  1. Custom Elements(自定义元素):是用户使用一组 JavaScript API 自己定义生成的包含行为和标记名称的自定义模板,是完全有效的 HTML 元素。
  2. shadow DOM(影子 DOM):能够隔离 CSS 和 JavaScript。
  3. HTML templates(HTML 模板):用户在 HTML 中定义的模板,在调用之前不会呈现(<template>....</template>)。

web components 在主流浏览器中的到支持,对于像 IE 这种经常不支持新内容的浏览器我们有 polyfills 。

组成 web components 的三种技术可以独立使用,也可以与其他任何一种或两种技术结合使用,他们之间并不互相排斥。

HTML template

HTML 模板不会立即呈现,但可以通过 js 调用,并允许我们重复引用其内部结构。下面是模板的简单形式:

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

<ul id="books"></ul>

示例模板在 js 调用之前不会呈现任何内容,需要我们实例化代码并告诉浏览器如何处理它。

// 选取模板的代码片段
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 => {
  // 复制模板中的内容,随后将其附加到相应的位置
  const instance = document.importNode(fragment.content, true);
  // 添加要展示的内容
  instance.querySelector('.title').innerHTML = book.title;
  instance.querySelector('.author').innerHTML = book.author;
  // 将要展示的结构附加到 DOM
  document.getElementById('books').appendChild(instance);
});

需要引起你注意的是 document.importNode 方法,此函数将创建模板内容的副本,并准备将其插入到另一个文档(或文档片段)中。函数的第一个参数是获取模板的内容,第二个参数是告诉浏览器对模板元素的 DOM 子树进行深层复制(即所有子节点)。

当然我们也可以不复制,直接使用 document.getElementById('books').appendChild(template.content),但是这样做会把模版的内容从模版元素中删除并附加到 body 中。如果后续再要使用模板的内容将得到空文档片段。使用 document.importNode 允许我们在多个位置重用相同模板内容。

<template></template> 具有多功能性,允许我们把 css 和 js 都放在其内部,使其具有特定的样式和行为。

下面我们创建一个将要在后文使用到的对话框模板,demo1:

<template id="one-dialog">
  <script>
    // 打开弹框的操作
    document.getElementById('launch-dialog').addEventListener('click', () => {
      const wrapper = document.querySelector('.wrapper');  // 弹框
      const closeButton = document.querySelector('button.close'); // 关闭按钮
      const wasFocused = document.activeElement; // 当前激活的元素
      wrapper.classList.add('open'); // 为弹框添加 open 属性
      closeButton.focus(); // 关闭按钮聚集
      closeButton.addEventListener('click', () => { // 关闭弹框的操作
        wrapper.classList.remove('open'); // 移除弹框上 open 属性
        wasFocused.focus(); // 激活元素聚焦 id=“launch-dialog” 的 button
      });
    });
  </script>
  <style>
    .wrapper { opacity: 0; transition: visibility 0s, opacity 0.25s ease-in; }
    .wrapper:not(.open) { visibility: hidden; }
    .wrapper.open {
      align-items: center; display: flex; justify-content: center;
      height: 100vh;
      position: fixed; top: 0; left: 0; right: 0; bottom: 0;
      opacity: 1; visibility: visible;
    }
    .overlay {
      background: rgba(0, 0, 0, 0.8);
      height: 100%; width: 100%;
      position: fixed; top: 0; right: 0; bottom: 0; left: 0;
    }
    .dialog { background: #ffffff;
      max-width: 600px;
      padding: 1rem;
      position: fixed;
    }
    button {
      all: unset;
      cursor: pointer;
      font-size: 1.25rem;
      position: absolute; top: 1rem; right: 1rem;
    }
    button:focus { border: 2px solid blue; }
  </style>
  <div class="wrapper">
    <div class="overlay"></div>
    <div class="dialog" role="dialog" aria-labelledby="title" aria-describedby="content">
      <button class="close" aria-label="Close">&#x2716;&#xfe0f;</button>
      <h1 id="title">Hello world</h1>
      <div id="content" class="content">
        <p>This is content in the body of our modal</p>
      </div>
    </div>
  </div>
</template>

 

<button id="launch-dialog">Launch dialog</button>
#launch-dialog {
  background: tomato;
  border-radius: 4px;
  color: #fff;
  font-family: Helvetica, Arial, sans-serif;
  padding: 0.5rem 1rem;
  position: static;
}
const template = document.getElementById('one-dialog');

document.body.appendChild(
  document.importNode(template.content, true)
);

当我们使用模板时,你会发现模板中的样式和脚本没有只作用于我们的模板,而是应用于整个文档,当我们将多个模板实例添加到 DOM 时,会出现不太理想的效果。在下文中,我们将创建自己的元素,使用该模板并封装元素的行为。

Custom Elements

custom elements  web components 的核心。

custom elements 是 HTML 元素,就像 <div><section> 或者 <article> 一样,我们可以通过浏览器 API 定义自己的名字,但是名字中必须包含一个或多个连接符(-),以便与原生 HTML 相区分,形如 <one-dialog></one-dialog>。同时,浏览器厂商不仅已经承诺不会在名称中创建包含连接符的新内置元素以防止冲突,还致力于保持规范持续向后兼容性。

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

从本质上讲,一个自定

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值