Невозможно отобразить ванильный веб-компонент, импортированный как шаблон - PullRequest
0 голосов
/ 10 декабря 2018

Я пытаюсь создать веб-компонент и импортировать его в основной файл HTML.

my 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>

Когда я использую <ns-tile /> непосредственно в index.html, содержимое отображается правильно.Но когда я пытаюсь отобразить его в цикле for в методе buildTile, я получаю сообщение об ошибке Uncaught TypeError: Cannot read property 'ownerDocument' of null at HTMLElement.connectedCallback (tile.html:16)

Как я могу получить доступ к html-шаблону внутри tile.html, чтобы я мог строить, используя for петля?

1 Ответ

0 голосов
/ 10 декабря 2018

Несколько вещей:

  1. Пользовательские элементы никогда не закрываются самостоятельно.<ns-tile /> следует заменить на <ns-tile></ns-tile>
  2. <link rel="import" href=""> мертв.Просто загрузите файл сценария обычным способом или используйте вместо него ES6 Import .
  3. Если вы продолжаете использовать link rel="import", тогда вы должны переместить var importedDoc = document.currentScript.ownerDocument; за пределы своего класса.
  4. Я нигде не вижу, чтобы вы «определяли» свой компонент: 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>
...