gpt4 book ai didi

css - 如何让 light dom css 应用于 shadow dom 元素?

转载 作者:太空宇宙 更新时间:2023-11-04 00:51:51 25 4
gpt4 key购买 nike

我定义了自己的自定义元素并发现在影子 dom 中添加其子元素很方便,主要是因为我可以在自定义元素构造函数中添加它,而同一个构造函数不允许我添加“常规” children 。

自定义元素的构造函数不允许您添加子元素,因为新元素在创建后应该立即为空。

我想知道是否有一种简单的方法可以使文档中的 css 和样式可以影响 shadow dom 中的元素。我希望 light dom 中的选择器能够到达 shadow dom 中的这些元素。

我的自定义元素之一是“元素”。我将创建很多它们来填充列表。我不喜欢在每个元素的实例的影子 dom 中重复完全相同的样式标签,所以我正在寻找一个地方来为我的所有元素放置这个样式标签。

我读了很多关于 shadow dom 以及内部样式如何不影响边界外元素的文章,但其中任何一篇都回答了我的问题。

有什么想法吗?谢谢!

最佳答案

当前版本的 shadowDOM 要求您将 CSS 放在 shadowDOM 中。

大多数 CSS 相当小,每个元素只增加几个字节到几百个字节。我见过的一些最大的网站在每个副本中添加了大约 2k 的 CSS。但这与 DOM 结构中表示的数据相比仍然很小。

有一些东西会从外部渗透出来,比如字体信息,但不是很多。

以下是您可以从外部影响的一些方法:

1。 CSS 变量

A CSS Variable允许您将变量设置为在 CSS 中使用的值,无论是否在 shadowDOM 中。

2。属性

可以捕获属性并将其迁移到 shadowDOM CSS 中。我有一些组件使用属性来定义主题。

3。属性

属性也可以应用于内部 CSS。

还有其他的方法正在讨论中,但是这些要等到V2了。

class MyEL extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: 'open'}).innerHTML = `
<style>
.outer {
color: var(--myColor, 'black');
</style>
<div class="outer">
<h4>Title</h4>
<slot></slot>
</div>`;
}

static get observedAttributes() {
return ['bgcolor'];
}

attributeChangedCallback(attrName, oldVal, newVal) {
if (oldVal !== newVal) {
this.shadowRoot.querySelector('.outer').style.backgroundColor = newVal;
}
}

get border() {
return this.shadowRoot.querySelector('.outer').style.border;
}
set border(value) {
this.shadowRoot.querySelector('.outer').style.border = value;
}
}

customElements.define('my-el', MyEL);

setTimeout(() => {
document.querySelector('my-el').border = '2px dashed blue';
},1000);

const btn = document.getElementById('toggle');
let color = '';
btn.addEventListener('click', () => {
color = color === '' ? 'white' : '';
document.querySelector('my-el').style.setProperty('--myColor', color);
});
<my-el bgcolor="red"></my-el>
<hr/>
<button id="toggle">toggle</button>

已更新

正如我在下面的评论中所述,有一些 CSS 规则如果不被覆盖,它们将渗透到 shadowDOM 中。渗透的东西是colorbackgroundfont,以及其他与之相关的东西。

此代码显示了它们如何渗透的示例:

customElements.define('css-test', class extends HTMLElement {
constructor() {
super();
var shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `<h1>Header</h1>
<p>This is a <strong>strong</strong> string</p>
<p>This is <em>emphasis<em>.`;
}
});

const styles = document.createElement('style');
styles.textContent = `
* {
background-color: #900;
border: 1px solid #9876;
border-radius: 5px;
box-sizing: border-box;
box-shadow: 0 0 4px #0005;
color: #fff;
font: 24px Tahoma;
margin: 20px;
padding 20px;
text-align: center;
text-decoration: #ffd wavy underline;
text-shadow: 3px 3px 3px #0008;
transform: rotate(30deg);
}`;

function toggleCss(evt) {
if(styles.parentElement) {
styles.remove();
}
else {
document.body.appendChild(styles);
}
}
const toggleEl = document.getElementById('toggle');
toggleEl.addEventListener('click', toggleCss);
  <css-test></css-test>
<hr/>
<button id="toggle">Toggle CSS</button>

当您点击切换按钮时,您会看到颜色、背景颜色、字体等发生了变化。但是像旋转这样的事情只发生在组件上,而不发生在组件内的子元素上。这是一件好事。想象一下,您的用户可以在您的组件内旋转东西……您的整个组件都会崩溃。

我一直在寻找一篇很好的文章,它谈到了所有穿透但找不到的东西。以前看过,但是忘记收藏了。因此,如果有人找到该文章,请将其添加到下面的评论中。

现在这里是上面相同的代码,但有几处被覆盖,因此您可以看到您的组件如何覆盖外部所做的事情:

customElements.define('css-test', class extends HTMLElement {
constructor() {
super();
var shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `<style>
:host * {
background: white;
color: yellow;
font-size: 14px;
}
</style><h1>Header</h1>
<p>This is a <strong>strong</strong> string</p>
<p>This is <em>emphasis<em>.`;
}
});

const styles = document.createElement('style');
styles.textContent = `
* {
background-color: #900;
border: 1px solid #9876;
border-radius: 5px;
box-sizing: border-box;
box-shadow: 0 0 4px #0005;
color: #fff;
font: 24px Tahoma;
margin: 20px;
padding 20px;
text-align: center;
text-decoration: #ffd wavy underline;
text-shadow: 3px 3px 3px #0008;
transform: rotate(30deg);
}`;

function toggleCss(evt) {
if(styles.parentElement) {
styles.remove();
}
else {
document.body.appendChild(styles);
}
}
const toggleEl = document.getElementById('toggle');
toggleEl.addEventListener('click', toggleCss);
<css-test></css-test>
<hr/>
<button id="toggle">Toggle CSS</button>

关于css - 如何让 light dom css 应用于 shadow dom 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55728287/

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