9

如果我理解正确,创建 Web 组件的实例可以总结为创建影子根并复制标记,例如从模板到其中:

var Template = document.querySelector('#myTemplate');
var TemplateClone = document.importNode(Template.content,true);
TargetElement.appendChild(TemplateClone);

当然,如果模板在样式标签中包含 css 规则,这些规则也会被复制。因此,我们可以拥有属于 Web 组件内部标记的范围样式。

问题:

  1. 当我创建大量同一个 Web 组件的实例时,它是否会对性能产生影响,因为样式只是被复制而不是重用?
  2. 有没有办法在同一个 Web 组件的多个实例之间共享样式节点?
4

1 回答 1

10

它是否有任何性能影响......?

是的,这取决于有多少实例,以及在浏览器中实现的 CSS 引擎。您必须测试每个用例并考虑速度与内存消耗。

有没有办法在同一个 Web 组件的多个实例之间共享样式节点?

是的,您可以@import url 在这个 SO question 中使用 like。或者您可以选择不使用 Shadow DOM 并仅使用全局 CSS 样式。

2019 年更新

正如 Harshal Patil 所建议的,从 Chrome 73 和 Opera 60 开始,多个 Shadow DOM 可以采用相同的样式表。这样,样式表中的更新将应用于所有 Web 组件。

let css = new CSSStyleSheet
css.replaceSync( `div { color: red }` )

customElements.define( 'web-comp', class extends HTMLElement {
    constructor() {
        super()
        let shadow = this.attachShadow( { mode: 'open' } )
        shadow.innerHTML = `<div><slot></slot></div>`
        shadow.adoptedStyleSheets = [ css ]
    }
} )
color.oninput = () => css.replaceSync( `div { color: ${color.value} }` )
<web-comp>Hello</web-comp>
<web-comp>World</web-comp>
<input value=red id=color>

于 2017-03-07T12:10:58.230 回答