首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >影子域中的FontAwesome svg

影子域中的FontAwesome svg
EN

Stack Overflow用户
提问于 2020-05-04 15:33:56
回答 3查看 561关注 0票数 3

我试图在一个web组件中使用字体awsome js/svg库,但是图标不显示。这个是可能的吗?

我正在尝试在一个现有的webforms项目中实现一个angular组件,而不是css和脚本“出血”,还有其他的建议吗?iframe不是一个选项。

代码语言:javascript
复制
    <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>
EN

回答 3

Stack Overflow用户

发布于 2020-05-04 17:45:21

许多旧的those库使用document.来访问主DOM。

所以他们不能对shadowDOM中的内容做任何事情

这意味着你的目标是不放出脚本是不可能的。

字体-令人敬畏(脚本和样式)必须加载到主DOM中。

如果你不想在shadowDOM之外放出样式,你必须遵守规则:

  • 字体-非常棒的图标定义必须保留在主DOM

  • lightDOM是shadowDOM slotted content

的(主DOM)原版

  • lightDOM由主DOM设置样式

(如果元素本身在另一个shadowDOM中,则为其shadowDOM容器)

  • slotted lightDOM remains in lightDOM,is to it
  • <slot></slot>

(仅对其插槽进行了反射,仅反映在其插槽中)

  • 您不希望在每个lightDOM中重复定义FontAwesome图标

(你也可以完全不使用自定义元素)

代码语言:javascript
复制
    <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>    

  • 自定义元素可以访问整个DOM

解决方案:

编写自定义元素,该元素

  • creates自己的lightDOM
  • which是时隙<slot></slot> (reflected!not moved!)
  • takes configuration from attributes

代码语言:javascript
复制
    <awesome-icon background="lightcoral" color="red"></awesome-icon>
    <awesome-icon background="lightgreen" color="green"></awesome-icon>
    <awesome-icon></awesome-icon>

JSFidlle:

代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js" defer></script>
<script>
  customElements.define('awesome-icon', class extends HTMLElement {
    constructor() {
      super().attachShadow({mode: 'open'})
      .append(document.getElementById(this.nodeName).content.cloneNode(true));
    }
    connectedCallback() {
      let setProperty =
          (prop, value)=>this.shadowRoot.host.style.setProperty('--' + prop, value);
      setProperty('fa-background', this.getAttribute('background'));
      setProperty('fa-color', this.getAttribute('color'));
      // move icon HTML back to lightDOM so FontAwesome can style it
      this.innerHTML = this.shadowRoot.querySelector('#ICON').innerHTML;
    }
  });
</script>
<template id="AWESOME-ICON">
  <style>
    ::slotted(*) {
      /* lightDOM SPAN has higher Specificity, only way out is using !important */
      background: var(--fa-background,grey) !important;
      color: var(--fa-color,darkgrey) !important;
    }
  </style>
  <template id="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>
  <slot><!--lightDOM REFLECTED here--></slot>
</template>
<awesome-icon><!-- lightDOM CREATED here --></awesome-icon>
<awesome-icon background="lightcoral" color="red"></awesome-icon>
<awesome-icon background="lightgreen" color="green"></awesome-icon>
<style>
  span{
    background:lightblue; /* !important inside shadowDOM overrules these settings */
    color:red;
  }
</style>

使用shadowDOM和插槽时不是

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

代码语言:javascript
复制
<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>
票数 0
EN

Stack Overflow用户

发布于 2021-09-18 23:03:06

我发现了一种方法来渲染SVG字体可怕的图标在阴影dom。

docs中,@fortawesome/fontawesome-svg-core包提供了更多的控制

下面是我使用该https://codesandbox.io/s/romantic-panka-40xqm创建的示例

基本思想是,我们可以使用icon(faCamera).html[0]获得SVG HTML,并可以在卷影dom root中使用它。

代码语言:javascript
复制
import { icon } from "@fortawesome/fontawesome-svg-core";
import { faCamera } from "@fortawesome/free-solid-svg-icons";

icon(faCamera).html[0]
票数 0
EN

Stack Overflow用户

发布于 2021-12-03 02:59:57

Font Awesome有一个内置的方法来解析/搜索给定元素中的图标标签,以生成SVG。下面的代码应该适用于您的示例,或者非常接近您正在寻找的内容:

代码语言:javascript
复制
FontAwesome.dom.i2svg({
    node: document.querySelector('my-holder').shadowRoot
})

或者,如果你想变得更花哨,让它自动热加载任何字体,更棒的图标在一个更动态的web组件中:

代码语言:javascript
复制
connectedCallback() {
  if (this.isConnected) {
    FontAwesome.dom.i2svg({
        node: this.shadowRoot
    })
    FontAwesome.dom.watch({
      autoReplaceSvgRoot: this,
      observeMutationsRoot: this.shadowRoot
    })
    /** Other web component init on connected code here */
  }
}

FontAwesome是由font- name脚本设置的全局变量的名称。

不带参数的i2svg()会重新解析整个轻量级dom (注意,这是不必要的,因为默认情况下font watches已经监视dom的变化了)。有了一个参数,你就可以传递一个带有node属性的js对象,该对象指向某个元素(光或阴影),它会根据你的需要生成你的SVG。

对于那些想要在SPA/编译的js前端中做到这一点的人,请查看FA documentation,以获得更简单的导入解决方案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61587210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档