这是使用自定义元素的示例开发者.google.com https://developers.google.com/web/fundamentals/web-components/customelements:
let tmpl = document.createElement('template');
tmpl.innerHTML = `
<style>:host { ... }</style> <!-- look ma, scoped styles -->
<b>I'm in shadow dom!</b>
<slot></slot>
`;
customElements.define('x-foo-shadowdom', class extends HTMLElement {
constructor() {
super(); // always call super() first in the constructor.
// Attach a shadow root to the element.
let shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.appendChild(tmpl.content.cloneNode(true));
}
...
});
虽然这有效,但我发现这种方法奇怪地丑陋。 HTML 和 CSS 应驻留在 .html 和 .css 文件中,而不是作为 Javascript 字符串。
同时我不知道如何将这些内容移动到.html或.css文件中?
嗯,是的,我可以填充主 HTML 文件,即index.html
, with <template>
可能使用过的所有自定义元素的标签 - 但这是否违背了自定义元素的目的?
<link rel="import">
可能很有希望,但是它已被删除 https://developer.mozilla.org/en-US/docs/Web/Web_Components/HTML_Imports.
还有其他选择吗?
(或者我认为原始解决方案丑陋是错误的?)
你可以使用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()
and text()
是异步的,你必须添加async
before connectedCallback()
and await
在方法调用之前。
您还可以简单地使用以下命令获取单独的 CSS 内容<link>
在 HTML 代码中。
我认为原始解决方案丑陋是错误的吗?
是的,它很丑。
如果您想使用模板文字,则无需将其放入<template>
元素并克隆它。
相反,直接使用模板文字:
shadowRoot.innerHTML = `
<style>:host { ... }</style> <!-- look ma, scoped styles -->
<b>I'm in shadow dom!</b>
<slot></slot>
`;
请注意,模板文字与单独的 HTML 相比有一个优势:您可以轻松使用插入变量。增量 CLIC 计数器的示例:
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>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)