1

Я новичок в веб-компоненте. Я проверил некоторый пример, но я действительно не могу понять, как загрузить (вставить в DOM) содержимое отдельного веб-компонента. Начиная с this Я, например, поместить этот код в файл с именем My-element.html:веб-компонент (ваниль, без полимера): как загрузить <template>?

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

Это мой 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> 

Я на последней Chrome 56, поэтому я не требуется полипол. Я запускаю polyserve, и только «работает ли это?». появляется. Я попробовал (например, оригинальный пример) синтаксис «customElements.define» вместо «document.registerElement», но не будет работать. У вас есть идеи? И что мне изменить, если я не хочу использовать теневое пространство?

благодаря

ответ

5

Это потому, что когда вы делаете:

document.querySelector('#my-element'); 

... 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); 
    } 
}); 

Обратите внимание, что document.currentScript является глобальной переменной, поэтому он ссылается на ваш импортированный документ только тогда, когда он в настоящее время разобран. Вот почему это значение сохраняется в переменной (здесь: importedDoc), чтобы быть многоразовым позже (в constrcutor вызова)

Если у вас есть несколько импортировали документ, который вы можете изолировать его в замыкании (как объяснено in this post):

(function (importedDoc) 
{ 
    //register element 
})(document.currentScript.ownerDocument); 
+0

Спасибо! Таким образом, «document.registerElement» также неверен. – Johannes

+2

Если вы хотите использовать registerElement(), вы должны заменить constructor() на createdCallback(). Но лучше использовать новую стандартизованную версию customElements.define(). – Supersharp

+0

Отлично! спасибо вам – Johannes