【问题标题】:How do I <use> a named <tspan> element in an SVG document?如何在 SVG 文档中 <使用> 命名的 <tspan> 元素?
【发布时间】:2022-01-14 15:23:34
【问题描述】:

我正在尝试在 SVG 文档的早期定义 tspan,以便稍后可以将其嵌入到 text 中。至少在 Firefox 中,下面的代码不会产生这个结果。

<svg version="1.1" width="500" height="500" xmlns="http://www.w3.org/2000/svg">
    <defs>
        <tspan id="transcluded-text">This is a text</tspan>
    </defs>
    <text>
        <use href="#transcluded-text"/>
    </text>
</svg>

使用 Firefox 的 Inspect 工具,use 元素按预期包含一个影子 DOM (#shadow-root),但影子 DOM 本身是空的。

不使用 Javascript,是否可以像这样在 text 中嵌入 tspan

【问题讨论】:

  • 你没有。 元素不是 元素的有效子元素。

标签: svg


【解决方案1】:

text 元素只能包含文本内容子元素(因此,不能包含 &lt;use&gt;),defs 元素可以包含的唯一与文本相关的元素是 &lt;text&gt;。所以,这一切都表明&lt;tspan&gt;不能以这种方式使用。

<svg version="1.1" width="500" height="500" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <text x="10" y="20" font-size="20" id="transcluded-text">This is a text</text>
  </defs>
  <use href="#transcluded-text"/>
</svg>

【讨论】:

    【解决方案2】:

    因为你不能在&lt;use&gt;元素使用&lt;text&gt;元素;
    &lt;defs&gt; 内的&lt;tspan&gt;

    现代的Native Web 组件可以完成替换的工作:

    (这将导致您可能想要处理的 FOUC)

    <script>
      customElements.define("svg-use-replacer", class extends HTMLElement {
        connectedCallback() {
          setTimeout(() => { // make sure SVG is parsed
            this.querySelectorAll('use').forEach(use => {
              let href  = use.getAttribute("href");
              let tspan = this.querySelector(href);
              use.replaceWith(tspan); // .replaceWith was not available in IE
            });
            // if the bare <svg> is required in the DOM:
            // this.replaceWith(this.querySelector("svg"));
          });
        }
      });
    </script>
    
    <svg-use-replacer>
      <svg version="1.1" width="500" height="500" xmlns="http://www.w3.org/2000/svg">
        <defs>
          <tspan id="foo" stroke="green">Wonderful</tspan>
        </defs>
        <text x="10" y="20" font-size="20">
          Hello
          <use href="#foo" /> Web Component
        </text>
      </svg>
    </svg-use-replacer>

    注意事项

    • oldskool 的方法是附加一个,然后在解析元素之后在其上运行 JavaScript。

    • 对于 Web 组件,它完全无关何时定义了 Web 组件。
      您可以随时执行上述script

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-03
      • 1970-01-01
      • 2016-07-21
      • 2011-01-02
      相关资源
      最近更新 更多