【问题标题】:How to style descendants of element that was slotted (in the stylesheet of the shadowroot)?如何为插入的元素的后代设置样式(在 shadowroot 的样式表中)?
【发布时间】:2020-07-10 21:17:33
【问题描述】:

这是我的尝试,但 span 元素没有我希望的 deeppink 边框(我在 Google Chrome 83 中):

const d = document.querySelector('div')

const r = d.attachShadow({mode: 'open'})

r.innerHTML = `
  <style>
    /* This doesn't work as I was hoping: */
    ::slotted(p) span {
      border: 1px solid deeppink;
    }
    
    /* This doesn't work (and I wouldn't expect it to), but I tried it anyways: */
    ::slotted(span) {
      border: 1px solid deeppink;
    }
    
    /* This doesn't work either: */
    :host span {
      border: 1px solid deeppink;
    }
    
    /* This works, but not what I'm trying to do. */
    ::slotted(p) {
      background: #f9f9f9
    }
  </style>
  <slot></slot>
`
<div>
  <p><span>test</span></p>
  <p><span>test</span></p>
  <p><span>test</span></p>
  <p><span>test</span></p>
  <p><span>test</span></p>
</div>

我们如何为分布式(开槽)子代的后代设置样式?

【问题讨论】:

    标签: javascript html css shadow-dom


    【解决方案1】:
    • 插槽内容保留在 lightDOM 中,反映到一个
    • ::slotted(*) 只能使用 simple 选择器
    • 定位 lightDOM SKIN

    详细答案请参见: ::slotted CSS selector for nested children in shadowDOM slot

    更新:示例 &lt;div SLOT=Hello&gt; 内容不是 IN shadowDOM

    <my-element>
      <div slot=Hello>Hello reflected (slotted) lightDOM DIV</div>
    </my-element>
    
    <my-element>
      <div slot=NoSlot>Hello not slotted lightDOM DIV</div>
    </my-element>
    
    <script>
      customElements.define('my-element', class extends HTMLElement {
        constructor() {
          super()
            .attachShadow({mode: 'open'})
            .innerHTML=`<slot name=Hello><b>I am shadowDOM SLOT content</b></slot>`;
        }
        connectedCallback() {
          console.log(this.shadowRoot.querySelector('slot').innerHTML)
        }
      });
    </script>

    【讨论】:

    • 虽然这在技术上是答案(我也找到了 GitHub 线程),但我希望可以提升限制。将组合器与 ::slotted 一起使用是一个直观的想法。
    • (回复 Truskr 以外的其他读者)是的,直观,如果您继续认为插槽内容是 shadowDOM 的一部分。但是插入的内容不是 shadowDOM 的一部分,它在 lightDOM 中。您在 shadowDOM 插槽中看到的内容是 反射。在 lightDOM 中所做的任何更改都会立即反映到插槽。
    • 添加代码:如果插槽被 lightDOM 内容占用,则不会显示 slot 内的内容....但 innerHTML 仍然是 slot 内容(在 shadowDOM 中)
    • 相对于实际的 DOM 树,我在想直观。开槽的内容 DOM 树位于灯光树中。 “组合”树是一个在普通 DOM 中不存在的虚拟 IDEA(例如,它没有用 childNodes 表示)。所以当我想到::slotted(foo) bar的时候,我直觉上已经在想它是根据光照树进行选择的。否则它没有直观的意义,因为即使在开槽之后,除此之外就没有树了。开槽元素的后代在新位置“镜像”或“渲染”,当然,但我正在考虑选择它们。
    • 所以我认为选择器匹配light dom中的元素很直观。就像:host 选择 DOM 中的一个元素一样,::slotted 也会选择一个元素,并且选择的元素将在您找到它的地方(在 light DOM 中,用户操作的唯一 DOM)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    • 2020-08-11
    • 2014-07-15
    • 2023-03-24
    相关资源
    最近更新 更多