【问题标题】:Styling default slot in webcomponents样式化 webcomponents 中的默认插槽
【发布时间】:2020-04-15 19:25:48
【问题描述】:

在 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>

【问题讨论】:

    标签: angular web-component angular-elements native-web-component


    【解决方案1】:

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

    <style>
    ...
    
    slot:not([name])::slotted(*) {
      ...
    }
    
    ...
    </style>
    

    【讨论】:

      【解决方案2】:

      找到一些解决方法,直到有人找到更好的方法。我们可以使用 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
          }
      

      【讨论】:

        【解决方案3】:

        这是一种误解 slotted 内容被 移动 到 shadowDOM 中的 slots

        不是!;

        它在 lightDOM 中保持不可见,并且 REFLECTED 到它在 shadowDOM 中的 SLOT

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

        或者.. 要设置未命名插槽的样式,您可以在 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

        【讨论】:

        • 根据我的理解,我们每次使用时都必须设置元素(实际上是插槽)的样式,对吗?它不可重复使用——不是吗?我的意思是每当我们使用自定义元素时,我们都必须对元素样式进行必要的更改——破坏可重用性
        • 这与常规 HTML5 元素及其 CSS 的情况相同...因此,如果您有未命名的插槽(一个 PITA,请参阅 sn-p 中的 DIV 顺序),您必须将其包装在另一个自定义元素(就像您想要组件化的常规 HTML5 一样(是一个词)
        猜你喜欢
        • 2018-04-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-09
        • 2019-06-03
        • 1970-01-01
        • 1970-01-01
        • 2021-06-21
        相关资源
        最近更新 更多