【问题标题】:how to get a slot content in the css content property of a pseudo ;:before element (or :;after) in a web component?如何在 Web 组件中的伪 ;:before 元素(或 :;after)的 css content 属性中获取插槽内容?
【发布时间】:2019-11-24 23:24:13
【问题描述】:

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

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

【问题讨论】:

  • 到目前为止你尝试过什么代码?
  • 没有javascript编码是不可能的
  • @Nathaniel :我已经完成了两个版本,第一个版本在 web 组件的主机中带有 CSS 变量,第二个版本在 web 组件的 connectedcallback 事件期间带有 javascript 传播的主机中的属性。我正在寻找减少代码的解决方案。
  • @Supersharp:太糟糕了,这就是我要找的。​​span>

标签: css web-component pseudo-element


【解决方案1】:

您可以使用 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>

【讨论】:

    【解决方案2】:

    @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) 女巫,带有 attr(...)、var(...) 和 calc(...) ,可以帮助在 Web 组件中使用伪元素。 有人可以告诉我提出这个建议的方法吗???

    我为我糟糕的英语道歉(我是法国人,nobdy 很完美)。

    【讨论】:

      猜你喜欢
      • 2021-06-27
      • 1970-01-01
      • 2013-06-08
      • 2013-01-09
      • 1970-01-01
      • 2013-06-07
      • 1970-01-01
      • 2015-03-30
      • 1970-01-01
      相关资源
      最近更新 更多