svg 作为背景图像:xlink 到原始文档中的 id

Dom*_*ber 5 html svg

我们有一个内嵌到文档底部的图标库,例如

<svg xmlns="http://www.w3.org/2000/svg">
  <symbol id="icon1" viewBox="0 0 100 100">
    <rect x="0" y="0" width="100" height="100" fill="green"/>
  </symbol>
  <symbol id="icon2" viewBox="0 0 100 100">
    <rect x="0" y="0" width="100" height="100" fill="red"/>
  </symbol>
</svg>
Run Code Online (Sandbox Code Playgroud)

这些图标在我们需要的任何地方都被简单地引用,比如

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" width="16px" height="16px">
  <use xlink:href="#icon1"/>
</svg>
Run Code Online (Sandbox Code Playgroud)

现在有时我们需要使用图标作为背景图像,类似于

<div style="width:16px; height:16px; background-size:cover; background-image: url(//placehold.it/16x16)"></div>
Run Code Online (Sandbox Code Playgroud)

它可以使用svgs作为使用背景图片data:image/svg+xml数据URI描述在这里

<div style='width:16px; height:16px; background-size:cover; background-image:url(&apos;data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><rect x="0" y="0" width="100" height="100" fill="red"/></svg>&apos;)'></div>
Run Code Online (Sandbox Code Playgroud)

但是,从数据 URI 内部引用 ID 的工作方式不同:

<h3>referenced in <code>svg</code></h3>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" width="16px" height="16px">
  <use xlink:href="#icon"/>
</svg>

<h3>referenced in <code>background-image</code>
<div style="width:16px; height:16px; background-size:cover; background-image:url(&quot;data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 100 100'><use xlink:href='#icon'/></svg>&quot;)"></div>

<svg xmlns="http://www.w3.org/2000/svg">
  <symbol id="icon" viewBox="0 0 100 100">
    <rect x="0" y="0" width="100" height="100" fill="red"/>
  </symbol>
</svg>
Run Code Online (Sandbox Code Playgroud)

我假设data:image/svg+xml为文档创建了一个新的“上下文”,因此#icon指的是内部的一个节点data:image/svg+xml(它不存在,因为它在原始文档中)。

有没有办法引用原始文档(比如使用类似于ShadowRoot.hostShadow DOM API 的东西)?(也许像xlink:href=":host#icon"

我想到的唯一解决方法是使用 JavaScript 内联使用过的符号:

Array.from(document.querySelectorAll('[style*="data:image/svg+xml;utf8,"]'))
  .forEach(function(e) {    
    e.style.backgroundImage = getComputedStyle(e).backgroundImage.replace(
      /<use xlink:href='#([^']+)'\/>/g,
      function(match, id) {
        return document.getElementById(id).innerHTML.replace(/(^\s*|\s*$)/g, '').replace(/"/g, "'")
      }
    )
  })
Run Code Online (Sandbox Code Playgroud)
<h3>referenced in <code>background-image</code> with JS inlining</h3>
<div style="width: 16px; height: 16px; background-size: cover; background-image: url(&quot;data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 100 100'><use xlink:href='#icon'/></svg>&quot;)"></div>
<svg xmlns="http://www.w3.org/2000/svg">
  <symbol id="icon" viewBox="0 0 100 100">
    <rect x="0" y="0" width="100" height="100" fill="red"/>
  </symbol>
</svg>
Run Code Online (Sandbox Code Playgroud)

但我真的希望完全避免使用 JavaScript。

Pau*_*eau 5

这是一个常见问题的微妙变化。

有没有办法参考原始文档

答案是<img>作为或等加载的任何文件(包括以数据 URL 形式存在的文件)都background-image需要是自包含的。它们作为独立对象加载,并且不能引用其他文件。

您需要将 包含<symbol>在您的数据 URL 中。