如何让光dom css应用于阴影dom元素?

问题描述 投票:0回答:1

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

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

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

我的一个自定义元素是“项目”。我会创建很多来填充列表。我不喜欢在每个项目的实例'shadow dom中重复相同样式标记的想法,所以我正在寻找一个地方为我的所有项目添加此样式标记。

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

有什么想法吗?谢谢!

css dom shadow-dom
1个回答
2
投票

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

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

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

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

1. CSS variables

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

2. Attributes

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

3. Properties

也可以采用属性并将其应用于内部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>
© www.soinside.com 2019 - 2024. All rights reserved.