如何在 Web 组件中的伪 ;:before 元素(或 :;after)的 css 内容 属性 中获取插槽内容?

how to get a slot content in the css content property of a pseudo ;:before element (or :;after) in a web component?

好吧,我认为问题在标题中: 在具有 shadowRoot 的 Web 组件中,我想在伪 ::before 或 ::after 元素的内容 属性 中使用插槽 text-content。 这可以让我获得更多台词。

您有想法、建议或解决方案吗?

您可以使用 CSS 自定义属性作为 ::before::aftercontentslotchange 事件的来源来实现此目的:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>WC</title>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />

    <script>
      class XTest extends HTMLElement {
        constructor() {
          super();

          // add shadow dom and insert template content
          const shadowRoot = this.attachShadow({ mode: "open" });

          const template = document.getElementById("x-test-template");
          const templateContent = template.content;

          shadowRoot.appendChild(templateContent.cloneNode(true));
        }

        connectedCallback() {
          // get all the named slots
          const slots = this.shadowRoot.querySelectorAll("slot[name]");

          [...slots].forEach(slot => {
            // add a listener to run when the slot changes
            slot.addEventListener("slotchange", event => {
              // get the slot name
              const name = event.target.name;
              
              // get the slot content
              const text = event.target.assignedNodes()[0].textContent;

              // update the custom property
              this.style.setProperty(`--content-${name}`, `'${text}'`);
            });
          });
        }
      }

      customElements.define("x-test", XTest);
    </script>
  </head>

  <body>
    <template id="x-test-template">
      <style>
        :host {
          display: inline-block;
          position: relative;

          font-size: 2rem;
          padding: 2rem;
        }

        :host::before,
        :host::after {
          content: "";
          position: absolute;
          top: 0;

          font-size: 1rem;
        }

        :host::before {
          /* set the pseudo selector content to the custom property */
          content: var(--content-before, "");
          left: 0;
        }

        :host::after {
          /* set the pseudo selector content to the custom property */
          content: var(--content-after, "");
          right: 0;
        }

        slot[name] {
          display: none;
        }
      </style>

      <!-- slot for ::before -->
      <slot name="before"></slot>
      
      <!-- default slot -->
      <slot></slot>
      
      <!-- slot for ::after -->
      <slot name="after"></slot>
    </template>

    <x-test>
      <span slot="before">B</span>
      <span>Hello</span>
      <span slot="after">A</span>
    </x-test>
  </body>
</html>

@lamplightdev

感谢您的回答。

我一直在寻找尚不存在的东西。 所以我选择了一个带有 css var 和 setter 的解决方案来设置它:

class extends HTMLElement {
  set content(val) {
    this.setAttribute('data-content',val);
  }
  constructor() {
...

当然还有:

:host::before {
  content: attr(data-content);
...

这似乎是我想象中的更简单的解决方案。

我想建议 Web 标准开发人员创建一个新的 css 函数:slot(name) , with attr(...), var (...) 和 calc(...),可以帮助在 Web 组件中使用伪元素。 有人可以告诉我如何提出这个建议吗???

我为我糟糕的英语语言道歉(我是法语,nobdy's perfect)。