如何使用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>
标记)将在新插入的子树中代替 。
截至撰写本文时(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树连接到每个div ( div.attachShadow({ mode: 'open' })
)。
attachShadow
有两个mode
选项 : open
和closed
。 如果选择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中的输出外观:
另 请 参阅: 如何使用MutationObserver API进行DOM节点更改
翻译自: https://www.hongkiat.com/blog/html-template-slow-tag-shadow-dom/