无法呈现作为模板导入的香草 Web 组件

Not able to render vanilla webcomponent imported as template

我正在尝试构建一个网络组件并将其导入主 HTML 文件。

我的index.html:

<!DOCTYPE html>
<html>
<head>
  <link rel="import" href="./tile.html">
</head>
<body>
  <a href="javascript:;" onclick="buildTile()">Build</a>

  <ns-tile /> <!-- Works -->

  <div id="ns-search-results"></div>
<script> 
  async function buildTile() { 
    const results = document.getElementById('ns-search-results'); 
    for(let i = 0; i < 10; i++) { 
      var nsTile = document.createElement('ns-tile'); 
      results.appendChild(nsTile); 
    } 
  }
</script>
</body>
</html>

tile.html

<template id="ns-item-tile"> 
  <style> </style> 
  <div class="tile"> Tile content </div>
</template>
<script> 
class NSTile extends HTMLElement { 
  constructor() {
    super();
  } 

  connectedCallback() { 
    var importedDoc = document.currentScript.ownerDocument; 
    let shadowRoot = this.attachShadow({ mode: 'open' }); 
    const t = importedDoc.querySelector('#ns-item-tile'); 
    const instance = t.content.cloneNode(true); 
    shadowRoot.appendChild(instance); 

    function init() { 
      const head = shadowRoot.querySelector('.tile'); 
      head.addEventListener("click", function () { 
        console.log('click'); 
      }); 
    } 
    init(); 
  } 
} // init the element

customElements.define("ns-tile", NSTile);
</script>

当我在 index.html 中直接使用 <ns-tile /> 时,内容会正确呈现。但是当我尝试在 buildTile 方法中的 for 循环中渲染它时,出现错误 Uncaught TypeError: Cannot read property 'ownerDocument' of null at HTMLElement.connectedCallback (tile.html:16)

如何访问 tile.html 中的 html 模板,以便使用 for 循环进行构建?

一些事情:

  1. 自定义元素永远不会自动关闭。 <ns-tile /> 应替换为 <ns-tile></ns-tile>
  2. <link rel="import" href=""> 死了。只需正常加载脚本文件或使用 ES6 Import 代替。
  3. 如果您继续使用 link rel="import",那么您必须将 var importedDoc = document.currentScript.ownerDocument; 移出 class。
  4. 我在任何地方都看不到你 "defining" 你的组成部分:customElements.define('tag-name', className);

这里是对组件文件的一些更改。如果将其更改为 JS 文件,则它可能如下所示:

const template = `<style></style> 
<div class="tile"> Tile content </div>
`;

class NSTile extends HTMLElement { 
  constructor() {
    super();
    let shadowRoot = this.attachShadow({ mode: 'open' }); 
    shadowRoot.innerHTML = template; 

    const head = shadowRoot.querySelector('.tile'); 
    head.addEventListener("click", function () { 
      console.log('click'); 
    }); 
  } 
}

customElements.define('ns-tile', NSTile);
<ns-tile></ns-tile>