在 webcomponents 中设置默认插槽的样式

Styling default slot in webcomponents

在 webcomponents 中,我们有两种类型的插槽(命名插槽和默认插槽)。我们可以使用语法 slot[name]::slotted(*) 轻松设置命名槽的样式。但是有没有什么方法可以让我们设置默认插槽的样式,因为它们没有关联任何名称?

代码是这样的,我正在使用 Angular Elements。

<div class="topbar-item">
  <slot class="icon" name="icon"></slot>
  <span class="text">
   <slot></slot> <-- This is the slot i want to add styles, only if the slot has some data assigned. (need to add margin-left)
  </span>
</div>

找到一些解决方法,直到有人找到更好的方法。我们可以使用 slotchange 事件来确定是否有任何物品附加到插槽中。这样。

HTML

<slot (slotchange)="onSlotChanged($event)"></slot>

JS/TS

    onSlotChanged($event) {
       const slotHasData = $event.target.assignedNodes().length > 0;
       // Is event.target.assignedNodes().length return more than 0, it has nu of items attached to the slot
    }

这是一个误解 slotted 内容在 shadowDOM[=13] 中 MOVEDslots =]

不是!

它在 lightDOM 中保持 不可见 并且在 shadowDOM[=] 中 REFLECTED 它的 SLOT 13=]

这意味着您可以应用样式 内容被插入后(鼠标悬停在下面的代码中)

或者.. 要设置未命名插槽的样式,请在 lightDOM 中设置未命名内容的样式:

customElements.define("my-element", class extends HTMLElement {
  connectedCallback() {
    let template = document.getElementById(this.nodeName);
    this.attachShadow({
      mode: 'open'
    }).appendChild(template.content.cloneNode(true));
  }
})
my-element div {
  background: lightcoral;
  padding: 1em;
  margin-top:.5em;
}

my-element div:hover {
  background: lightgreen;
}

h1{
  background:lightblue;
  color:black;
  margin:0;
}
h1:hover {
  color: red;
}
<template id=MY-ELEMENT>
  <style>
    :host {
      display: block;
      padding:.5em;
      background:green;
    }
    ::slotted(*){
      color:white;
    }
    div{
      border:1px dashed black;
    }
  </style>
  <div>
  <slot name=title></slot>
  <slot></slot>
  </div>
</template>

<my-element>
  <div>Custom Elements Rule!</div>
  <h1 slot=title>Hello World!</h1>
  <div>What a wonderfull day!</div>
</my-element>

注意!所有未命名内容如何进入(一个)未命名 SLOT

您可以只使用 :not() 伪 class:

<style>
...

slot:not([name])::slotted(*) {
  ...
}

...
</style>