Вы можете использовать fetch()
, чтобы получить HTML-файл для содержимого пользовательского элемента.
customElements.define('x-foo-shadowdom', class extends HTMLElement {
constructor() {
super()
this.attachShadow( {mode: 'open'} )
}
async connectedCallback() {
let res = await fetch( 'x-foo.html' )
this.shadowRoot.innerHTML = await res.text()
}
}
Примечание: поскольку fetch()
и text()
являются асинхронными, необходимо добавить async
перед connectedCallback()
и await
перед вызовом метода.
Вы также можете получить отдельный контент CSS, просто используя <link>
в коде HTML.
Я ошибаюсь, чтобы найти оригинальное решение некрасиво?
Да, это ужасно.
Если вы хотите использовать литерал шаблона, вам не нужно помещать его в элемент <template>
и клонировать его.
Вместо этого используйте шаблонный литерал напрямую:
shadowRoot.innerHTML = `
<style>:host { ... }</style> <!-- look ma, scoped styles -->
<b>I'm in shadow dom!</b>
<slot></slot>
`;
Обратите внимание, что у литералов шаблона есть преимущество перед отдельным HTML: вы можете легко использовать переменные вставки. Пример с добавочным счетчиком кликов:
customElements.define( 'click-counter', class extends HTMLElement {
connectedCallback() {
let count = 0
let sh = this.attachShadow( { mode: 'open' } )
this.onclick = () => sh.innerHTML = `<button>${count++}</button>`
this.click()
}
} )
<click-counter></click-counter>