Shadow dom 内的 FontAwesome svg

use*_*186 5 javascript webforms web-component font-awesome angular

我正在尝试在 Web 组件中使用 font awsome js/svg 库,但图标不会显示。这可能吗?

我正在尝试在现有的 webforms 项目中实现一个角度组件,而无需 css 和脚本“流血”,关于如何做到这一点还有其他建议吗?iframe 不是一个选项。

    <html>
    <head>
        <script src="https://polygit.org/components/webcomponentsjs/webcomponents-loader.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js" defer>
        </script>
        <script>
            customElements.define('my-holder', class extends HTMLElement {
                constructor() {
                    super();

                    console.log("constructor");
                    let shadowRoot = this.attachShadow({
                        mode: 'open'
                    });

                    const t = document.querySelector('#holder');
                    const instance = t.content.cloneNode(true);

                    shadowRoot.appendChild(instance);
                }

                connectedCallback() {
                    console.log("callback");
                }
            });
        </script>
    </head>

    <body>
        <div id="outside">
            light dom
            <div class="fa-4x">
                <span class="fa-layers fa-fw" style="background:MistyRose">
                    <i class="fas fa-circle" style="color:Tomato"></i>
                    <i class="fa-inverse fas fa-times" data-fa-transform="shrink-6"></i>
                </span>
            </div>
        </div>

        <template id="holder">
            <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js" defer></script>
            dark shadow dom
            <div class="fa-4x">
                <span class="fa-layers fa-fw" style="background:MistyRose">
                    <i class="fas fa-circle" style="color:Tomato"></i>
                    <i class="fa-inverse fas fa-times" data-fa-transform="shrink-6"></i>
                </span>
            </div>
        </template>

        <div id="inside">
            <my-holder></my-holder>
        </div>

    </body>
    </html>
Run Code Online (Sandbox Code Playgroud)

Dan*_*man 2

许多 oldskool 库用于document.访问主 DOM。
因此他们无法对其中的内容执行任何操作shadowDOM

这意味着您不让脚本流失的目标是不可能的。
Font-Awesome(脚本和样式)必须加载到主 DOM 中。

如果您不想在 ShadowDOM 之外渗出样式,则必须遵守以下规则:

  • Font-Awesome 图标定义必须保留在主 DOM 中

  • lightDOM是ShadowDOM开槽内容的(主 DOM)“原始”

  • lightDOM 由主 DOM 设计
    (如果元素本身位于另一个 ShadowDOM 中,则为其 ShadowDOM 容器)

  • 开槽lightDOM 保留在 lightDOM 中,仅反射到其<slot></slot>

  • 您不想在每个 lightDOM 中重复 FontAwesome 图标定义
    (那么您最好根本不使用自定义元素)

    <span class="fa-4x fa-layers fa-fw">
      <i class="fas fa-circle"></i>
      <i class="fa-inverse fas fa-times" data-fa-transform="shrink-6"></i>
    </span>    
Run Code Online (Sandbox Code Playgroud)
  • 自定义元素可以访问整个 DOM

解决方案:

编写一个自定义元素

  • 创建自己的 lightDOM
  • 已开槽<slot></slot>反射!未移动!
  • 从属性获取配置
    <awesome-icon background="lightcoral" color="red"></awesome-icon>
    <awesome-icon background="lightgreen" color="green"></awesome-icon>
    <awesome-icon></awesome-icon>
Run Code Online (Sandbox Code Playgroud)

JSFdlle:https://jsfiddle.net/CustomElementsExamples/1pmvasnj/

    <span class="fa-4x fa-layers fa-fw">
      <i class="fas fa-circle"></i>
      <i class="fa-inverse fas fa-times" data-fa-transform="shrink-6"></i>
    </span>    
Run Code Online (Sandbox Code Playgroud)

使用 ShadowDOM 和 SLOT

并依赖作用域 CSS 属性,使代码更简单:

<script>
  customElements.define('awesome-icon', class extends HTMLElement {
    connectedCallback() {
      this.append(document.getElementById(this.nodeName).content.cloneNode(true));
      this.style.setProperty('--fa-background', this.getAttribute('background') );
      this.style.setProperty('--fa-color'     , this.getAttribute('color')      );
    }
  });
</script>

<template id="AWESOME-ICON">
  <span class="fa-4x fa-layers fa-fw">
     <i class="fas fa-circle"></i>
     <i class="fa-inverse fas fa-times" data-fa-transform="shrink-6"></i>
  </span>
</template>

<awesome-icon background="lightcoral" color="red"></awesome-icon>
<awesome-icon background="lightgreen" color="green"></awesome-icon>
<awesome-icon></awesome-icon>

<style>
  span {
    background: var(--fa-background);
    color:      var(--fa-color     );
  }
</style>
Run Code Online (Sandbox Code Playgroud)