gpt4 book ai didi

css - 向 shadowDOM 中动态创建的样式表添加规则

转载 作者:行者123 更新时间:2023-11-27 23:22:24 25 4
gpt4 key购买 nike

我最近开始接触 WebComponents,我必须说到目前为止我发现它具有开创性!为了更好地理解这个概念,我尝试将我早期元素中的设计应用到可重用的 Web 组件中。我首先尝试创建一个具有一些附加功能的 Table 元素。

首先,我为组件声明了一个最小模板:

<template id="data-table-template">
<table>
<thead></thead>
<tbody></tbody>
<tfoot></tfoot>
</table>
</template>

我使用此模板通过将表 header value 和行值作为属性来创建表。该元素按以下方式使用:

<eur-data-table
headers="getHeaders()",
rowdata="getRowData()"
host="#data-table-host"
template="#data-table-template"
></eur-data-table>

在组件原型(prototype) connectedCallback 方法中,我为组件添加了标题、行和设置样式。 Chrome Element inspector 生成的影子 DOM 片段如下:

<eur-data-table headers="getHeaders()" ,="" rowdata="getRowData()" host="#data-table-host" template="#data-table-template" theme="firebrick">
<table>
<style id="styleBlock"></style>
<thead>
<th>Name</th>
<th>Age</th>
</thead>
<tbody>
<tr>
<td>Babu</td>
<td>60</td>
</tr>
<tr>
<td>Shyam</td>
<td>35</td>
</tr>
</tbody>
<tfoot></tfoot>
</table>
</eur-data-table>

问题在于添加样式规则。在组件类中,我创建了一个 style 元素,并在将规则添加到 style.sheet 属性之前将其附加到影子 DOM。我检查了 style.sheet 的控制台输出,看起来所有规则都已添加。但是,在将样式元素插入影子 DOM 后,从上面的渲染输出中可以看出没有任何规则。

在组件类中,通过以下方式添加样式:

connectedCallback() {
let template = document.querySelector(DataTable._parseId(this.template));
if(!template) throw new DOMException('Host and/or template ids are undefined');
if(!this.hasAttribute('theme')) this.setAttribute('theme', 'firebrick');

let style = document.createElement('style');
style.setAttribute('id', 'styleBlock');
// WebKit Hack
style.appendChild(document.createTextNode(""));
this.shadowRoot.appendChild(style);

this._table = template.content.cloneNode(true);
this._setupHeaders();
this._setupBody();
this._setupStyle(style.sheet); // style is not being applied!!
console.dir(style.sheet); // logs a CSSStyleSheet object
this.shadowRoot.appendChild(this._table);
}

connectedCallback 方法中,_setupStyle 被传递到样式表的引用,它以下列方式添加规则(规则表示为 javascript 对象) :

_setupStyle(sheet) {
if(!sheet) throw new DOMException('sheet is undefined', 'StylesheetNotFoundException');
let rules = window.themes[this.theme];
if(!rules) throw new DOMException('Theme is undefined');

Object.keys(rules)
.sort((r1, r2) => rules[r1].order - rules[r2].order)
.forEach(rule => {
let o = _.omit(rules[rule], 'order');
let i = rule.order;
let s = this._makeRule(o, rule);
sheet.insertRule(s, i);
});
}

order 值是一个整数,用于按顺序对样式规则进行排序。排序后,order 键及其值在将对象转换为 DOMString 之前从对象中省略:

_makeRule(value, rule) {
return `${rule} ${JSON.stringify(value).replace(new RegExp(/,/g), ';')}`;
}

记录 style.sheet 属性打印:

CSSStyleSheet
cssRules: CSSRuleList
0: CSSStyleRule {selectorText: "tfoot", style: CSSStyleDeclaration, styleMap: StylePropertyMap, type: 1, cssText: "tfoot { }", …}
1: CSSStyleRule {selectorText: "tr:last-child > td", style: CSSStyleDeclaration, styleMap: StylePropertyMap, type: 1, cssText: "tr:last-child > td { }", …}
2: CSSStyleRule {selectorText: "td:last-child", style: CSSStyleDeclaration, styleMap: StylePropertyMap, type: 1, cssText: "td:last-child { }", …}
3: CSSStyleRule {selectorText: "td", style: CSSStyleDeclaration, styleMap: StylePropertyMap, type: 1, cssText: "td { }", …}
4: CSSStyleRule {selectorText: "tr:first-child", style: CSSStyleDeclaration, styleMap: StylePropertyMap, type: 1, cssText: "tr:first-child { }", …}
5: CSSStyleRule {selectorText: "tr:last-child", style: CSSStyleDeclaration, styleMap: StylePropertyMap, type: 1, cssText: "tr:last-child { }", …}
6: CSSStyleRule {selectorText: "tr", style: CSSStyleDeclaration, styleMap: StylePropertyMap, type: 1, cssText: "tr { }", …}
7: CSSStyleRule {selectorText: "th:last-child", style: CSSStyleDeclaration, styleMap: StylePropertyMap, type: 1, cssText: "th:last-child { }", …}
8: CSSStyleRule {selectorText: "th", style: CSSStyleDeclaration, styleMap: StylePropertyMap, type: 1, cssText: "th { }", …}
9: CSSStyleRule {selectorText: "thead", style: CSSStyleDeclaration, styleMap: StylePropertyMap, type: 1, cssText: "thead { }", …}
10: CSSStyleRule {selectorText: "thead tbody tfoot", style: CSSStyleDeclaration, styleMap: StylePropertyMap, type: 1, cssText: "thead tbody tfoot { }", …}
11: CSSStyleRule {selectorText: "table", style: CSSStyleDeclaration, styleMap: StylePropertyMap, type: 1, cssText: "table { }", …}

我的问题是:由于组件的渲染没有错误,而且我按预期添加了所有规则并将两者附加,样式和表格元素到影子 DOM 渲染了预期的元素,那么为什么我的不是CSS 规则应用于呈现的内容?

最佳答案

暂时,直到shadow parts api变得可用(这将允许我们将整个元素声明为可由消费者设置样式)

我建议使用大量 custom css properties (样式 Hook )为消费者提供一种影响 Web 组件样式的方法

出于主题化的目的,提议的属性 adoptedStyleSheets 可能有一些 polyfill 支持,但我只是在一些线程中偶然提到它,所有这些都像谣言一样

关于css - 向 shadowDOM 中动态创建的样式表添加规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57939797/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com