【问题标题】:Share style across web components "of the same type"在“相同类型”的 Web 组件之间共享样式
【发布时间】:2017-07-27 11:42:39
【问题描述】:

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

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

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

问题:

  1. 当我创建大量的 同一个 Web 组件的实例,因为样式只是 复制而不重复使用?
  2. 有没有办法跨多个实例共享样式节点 相同的网络组件?

【问题讨论】:

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


【解决方案1】:

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

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

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

是的,您可以使用@import url like in this SO question。或者你可以选择不使用 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>

【讨论】:

  • 它是不是仍然在标记中重复,只是不同的是,它是从外部 url 加载的(当然结果是缓存的)?
  • 是与否,标记不会重复,但会在元素的 DOM 中添加一个 stylesheet 对象。无论如何,DOM 中的每个元素都是单独设置样式的,因此元素(和样式)越多,样式处理过程就越长,无论样式是否共享。我不知道复制样式表的开销,但也许不是那么多。它应该随用例(以及 css 引擎实现)而变化
  • @MichaelK 感谢您接受的答案。如果有帮助,您可以投票 :-)
  • 重要 以上代码需要 Chrome 73。这是 2019 年 3 月 12 日 上的 scheduled for official release,所以您现在需要在 Chrome Canary 'for Developers' 中打开此示例(撰写本文时是 2 月 23 日
  • @Supersharp,我可以建议将代码示例中的onchange 更改为oninput,为HTML 颜色名称提供更直接的反馈
猜你喜欢
  • 2019-02-09
  • 2010-09-20
  • 1970-01-01
  • 2019-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多