自定义元素中断模板上的createElement

时间:2017-03-06 03:39:48

标签: web-component shadow-dom custom-element html-imports html5-template

我正在创建两个自定义元素,都使用link rel =“import”添加到index.html。一个是带插槽的容器,另一个是插槽中的数字。这两个元素都有一个带有模板的HTML文件和一个指向js文件的链接,该文件将它们定义为自定义元素。要将自定义元素类声明链接到我正在使用的HTML模板:

pandoriclet

这个拼图元素和容器正确渲染,当你手动将它们放入index.html light dom时它都可以正常工作

class PuzzlePiece extends HTMLElement{

constructor(){
    super();
    console.dir(document.currentScript);
    const t = document.currentScript.ownerDocument.getElementById('piece-puzzle');
    const shadowRoot = this.attachShadow({mode: 'open'});
    shadowRoot.appendChild(t.content.cloneNode(true));
 }

然而,一旦我尝试在index.html中使用JS创建和附加拼图:

<special-puzzle id="grid">
    <puzzle-piece id="hello"></puzzle-piece>
 </special-puzzle>

我在特殊拼图灯dom中看到一个新的拼图,但它没有占用一个插槽,没有渲染,并且控制台有错误:

  

未捕获的TypeError:无法读取null的属性“content”       在新的PuzzlePiece(puzzle-piece.ts:8)       在HTMLDocument.createElement(:3:492)       在(指数):37

据我所知,问题是当使用document.createElement时,浏览器会进入类定义,但document.currentScript.ownerDocument与仅手动使用HTML标记时不同。我相信因此,组件找不到它的模板。这是我的第一个Stack Overflow问题,所以任何反馈/帮助都会受到赞赏!

1 个答案:

答案 0 :(得分:2)

感谢真棒的@Supersharp和他们的Stack Overflow post

基本上,为了保留正确的document.currentScript.ownerDocument,我需要在类之前在var中声明它,然后在类中使用该var。

旧:

class PuzzlePiece extends HTMLElement{
constructor(){
super();
const t = document.currentScript.ownerDocument.getElementById('piece-puzzle');
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.appendChild(t.content.cloneNode(true));}

新:

var importedDoc = document.currentScript.ownerDocument;
class PuzzlePiece extends HTMLElement{
constructor(){
super();
const t = importedDoc.getElementById('piece-puzzle');
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.appendChild(t.content.cloneNode(true));}