如何使用HTML 和 使用Shadow DOM

HTML插槽是W3C制定的最杰出的标准之一。 将其与另一个令人印象深刻的W3C标准(称为模板)结合使用,您将获得绝佳的配合。 能够使用JavaScript 创建HTML元素并将HTML元素添加到页面是一项必要且重要的任务。

当代码片段仅在特定时间出现时 ,或者当您不想键入数百个结构类似HTML元素但想要使过程自动化时,它很有用。

另请参阅: Web开发人员用于DOM操作的15种JavaScript方法

在JavaScript中创建HTML元素不是很理想 麻烦的是必须检查并重新检查是否覆盖了所有标签,并以正确的顺序放置它们,总之,键入和跟踪的内容太多了。 但是,当<template>标签出现时,这种动荡得到了解决 如果需要将某些内容动态添加到页面中 ,可以将其放在<template>元素内。

在本文中,我将向您展示如何将<slot><template>标记与JavaScript一起使用,以创建一个微型HTML表工厂 ,该工厂可以创建并填充数百个相似的表。

<slot><template>标签

<template>标记包含HTML代码,除非使用JavaScript将其正确添加到文档中,否则HTML代码不会被浏览器呈现 <slot>标记是添加到Shadow DOM占位符,占位符可以由<template>元素的内容组成。

Shadow DOM与常规DOM(从HTML解析的文档模型)相似。 创建一个作用域树 (一个影子DOM树),该树具有自己并且也可以具有自己样式

当您将Shadow DOM树插入主文档中的某个元素时(该元素将被称为Shadow host ),该Shadow Host的所有子元素都标有slot属性 (与前面提到的<slot>标记)将在新插入的子树中代替

如何使用HTML 和 使用Shadow DOM
html-template-slow-tag-shadow-dom:W3C

截至撰写本文时(2017年7月),Shadow DOM 仅在基于WebKit和Blink的浏览器受支持,但您可以随时在CanIUse上检查浏览器支持的实际状态。

设置HTML <template>

还是令人困惑? 让我们看一些代码,从<template>元素开始。

<template> ,有一个<table>用作创建一些表 的蓝图这些表将添加到文档中。 表单元格( <th><td> )内有<slot>元素, 用作列标题和单元格值的占位符 每个插槽都有一个唯一的name属性来标识它

<template>
  <table>
    <tr>
      <th><slot name='title-1'></slot></th>
      <th><slot name='title-2'></slot></th>
    </tr>
    <tr>
      <td><slot name='value-1.1'></slot></td>
      <td><slot name='value-1.2'></slot></td>
    </tr>
    <tr>
      <td><slot name='value-2.1'></slot></td>
      <td><slot name='value-2.2'></slot></td>
      </tr>
  </table>
  <style>
    table {
        table-layout: fixed;
        border-collapse: collapse;
        margin-bottom: 10px;
    }
    th {
        width: 300px;
    }
    th,
    td {
        border: 1px solid;
    }
  </style>
</template>

在模板内部 ,我还使用<style>标签为表格添加了一些基本样式

模板之外 ,还有两个<div> 载列标题和单元格值中的元素<span>为两个独立的表,我们要添加到页面。

<div>
  <span slot='title-1'>Title A</span>
  <span slot='title-2'>Title B</span>
  <span slot='value-1.1'>Value A.1</span>
  <span slot='value-1.2'>Value A.2</span>
  <span slot='value-2.1'>Value B.1</span>
  <span slot='value-2.2'>Value B.2</span>
</div>

<div>
  <span slot='title-1'>Title C</span>
  <span slot='title-2'>Title D</span>
  <span slot='value-1.1'>Value C.1</span>
  <span slot='value-1.2'>Value C.2</span>
  <span slot='value-2.1'>Value D.1</span>
  <span slot='value-2.2'>Value D.2</span>
</div>

每个<span>元素都有一个slot属性,该属性的值等于 <template>相应的<slot>标记name

现在,您在页面上可以看到的只是跨度中包含的文本字符串,因此我们还需要添加一些JavaScript。

附加Shadow DOM树

使用Javascript,我们将表格从模板内部插入到两个div中, 作为Shadow DOM树 插入后,跨度将被放入表内的相应插槽中,并显示所需的列标题或单元格值。 结果将是两个使用相同模板的自动生成的表

首先,我们需要检查用户浏览器是否支持Shadow DOM。 attachShadow()方法将Shadow DOM树附加到元素,并返回该Shadow DOM树的根节点。 下面的代码中的if条件通过测试页面上的div是否具有attachShadow方法来检查浏览器是否支持此方法。

// check if Shadow DOM is supported
if ('attachShadow' in document.createElement('div')){

}
else
  console.warn('attachShadow not supported');

我们创建一个名为templateContent的自定义变量,该变量用作对模板内容的引用

if('attachShadow' in document.createElement('div')) {
  let templateContent = document.querySelector('template').content;
  let divs = document.querySelectorAll('div');

  divs.forEach(function(div) {
      // inside loop
  });
}
else
  console.warn('attachShadow not supported');

forEach循环内,Shadow DOM树连接到每个divdiv.attachShadow({ mode: 'open' }) )。

attachShadow两个mode选项openclosed 如果选择closed ,则影子DOM树的根节点将变得外部DOM元素和对象无法访问

然后,我们使用templateContent.cloneNode(true)方法将模板内容的副本添加到Shadow DOM树中。

if('attachShadow' in document.createElement('div')) {
  let templateContent = document.querySelector('template').content;
  let divs = document.querySelectorAll('div');

  divs.forEach(function(div){
    div.attachShadow({  mode: 'open' }).appendChild(
        templateContent.cloneNode(true))
  });
}
else
  console.warn('attachShadow not supported');

并且,我们的动态HTML表已准备就绪,这是在Chrome中的输出外观:

如何使用HTML 和 使用Shadow DOM

参阅: 如何使用MutationObserver API进行DOM节点更改

翻译自: https://www.hongkiat.com/blog/html-template-slow-tag-shadow-dom/