web组件(香草,没有聚合物):如何加载<template>内容?

Joh*_*nes 1 javascript web-component html5-template custom-element html-imports

我是网络组件的新手.我检查了一些例子,但我真的无法弄清楚如何加载(插入DOM)一个单独的Web组件的内容.从这个例子开始,我把这段代码放在一个名为my-element.html的文件中:

<template id="my-element">
  <p>Yes, it works!</p>
</template>
<script>
    document.registerElement('my-element', class extends HTMLElement {
      constructor() {
      super(); 
      let shadowRoot = this.attachShadow({mode: 'open'});
      const t = document.querySelector('#my-element');
      const instance = t.content.cloneNode(true);
      shadowRoot.appendChild(instance);
    }
});
</script>
Run Code Online (Sandbox Code Playgroud)

这是我的index.html:

<!doctype html> 
<html>
 <head>
   <meta charset="utf-8">
   <title>my titile</title>
   <link rel="import" href="my-element.html">
</head>
<body>
  Does it work?
  <my-element></my-element>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

我在使用最新的Chrome 56,所以我不需要填充.我运行polyserve,只有"它有效吗?" 出现.我尝试(像原始示例)"customElements.define"语法而不是"document.registerElement",但不起作用.你有什么想法吗?如果我不想使用影子dom,我还能改变什么?

谢谢

Sup*_*arp 7

这是因为当你这样做时:

document.querySelector( '#my-element' );
Run Code Online (Sandbox Code Playgroud)

... document指的是主文档index.html

如果你想获得模板,你应该使用 document.currentScript.ownerDocument

var importedDoc = document.currentScript.ownerDocument;
customElements.define('my-element', class extends HTMLElement {
      constructor() {
          super(); 
          let shadowRoot = this.attachShadow({mode: 'open'});
          const t = importedDoc.querySelector('#my-element');
          const instance = t.content.cloneNode(true);
          shadowRoot.appendChild(instance);
    }
});
Run Code Online (Sandbox Code Playgroud)

请注意,这document.currentScript是一个全局变量,因此它仅在您当前解析时才引用您导入的文档.这就是为什么它的值保存在一个变量(这里importedDoc:)以后可以重复使用(在constrcutor调用中)

如果您有多个导入文档,你可能需要将其隔离在封闭(如解释在这个职位):

( function ( importedDoc )
{
    //register element
} )(document.currentScript.ownerDocument);
Run Code Online (Sandbox Code Playgroud)

  • 如果要使用registerElement(),则应使用createdCallback()替换constructor().但最好使用新的标准化版本customElements.define(). (2认同)