香草网络组件结构

Vanilla web-component structure

我正在研究构造香草网络组件。我以前使用过 Polymer,我喜欢这样一个事实,即您可以在一个文件中为您的组件提供模板、样式和 JavaScript。如果可能的话,我想用 'vanilla' 网络组件来实现这一点,但不知道如何实现。我从 here 中获取代码并将其添加到我正在使用的文件中,如下所示:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <title>Component test</title>
    
    <link rel="import" href="x-foo-from-template.html">
  </head>
  <body>
    <x-foo-from-template></x-foo-from-template>
  </body>
</html>

这失败了,因为当我们尝试 select 模板时它不存在,因为此时模板不在 DOM(对吗?)。

有什么办法可以实现吗?我个人更喜欢这种使用 document.createElement.

在 JavaScript 中创建 HTML 的方法

从导入的文档中获取模板主要有两种方法:

1.来自import属性的<link>元素

<link rel=import> 元素拥有包含导入文档的 import 属性。 您可以对其执行 querySelector 调用以获取 <template>:

var doc = document.querySelector( 'link[href$="x-foo-from-template.html"]').import
var template = doc.querySelector( 'template' )

然后使用 importNode()cloneNode().

在自定义元素(或其影子 DOM)中导入模板

2。形成currentScript

ownerDocument属性

解析脚本时,全局值 document.currentScript 引用正在解析的脚本,因此它的 属性 ownerDocument 是对拥有该脚本的文档的引用。您可以对其执行 querySelector 调用:

var template = document.currentScript.ownerDocument.querySelector( 'template' )

注意:currentScript的值是临时设置的,所以在后续的调用中将不再起作用,像 connectedCallback()attachedCallback(),所以你必须在解析时将它记住在一个持久变量中,以便在以后需要时重用它。

迟到者:

自 2021 年起,HTML 导入功能已被弃用 (MDN Link)。

我不推荐它,您可以改为:创建一个带有 data- 属性的模板标签以 html 导入。编写一个脚本,在所有具有该属性的元素上运行,并在脚本中使用 fetch() 访问那些 html 部分,将获取的导入添加到模板标签并使用它,例如:template.content.cloneNode( true )