将渲染的SVG图像转换为嵌入式SVG,而无需重新加载外部文件?

时间:2019-03-14 01:03:15

标签: javascript html svg

这两个问题herehere相似但不相同。

假设这样的元素链接到外部SVG图像:

<div style="background-image: url("/images/tags/icon/star.svg");"></div>

如果该图像已经作为背景图像渲染,那么将此SVG图像转换为嵌入式SVG(文档中的其他位置)有哪些选择?

this answer中建议的唯一重新加载外部文件的选项吗?

目标是在可能的情况下再次跳过加载SVG文件。

1 个答案:

答案 0 :(得分:1)

还有其他解决方案,但是如果您打算在文档中附加SVG,则AJAX确实是最简单的。
但是请注意,这可能不是一个好主意。
您可能知道,SVG是文档,它们的节点可以具有id属性。 id属性在每个文档中必须是唯一的,因此,如果将包含id的节点的同一svg文档附加两次,则会有重复的ID,并且可能有问题。

const svg = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">
  <defs>
    <rect id="rect1" x="0" y="0" width="50" height="50" fill="red"/>
  </defs>
  <use xlink:href="#rect1" stroke="green"/>
</svg>`;

function appendSVGDoc(markup, parent) {
  const doc = (new DOMParser).parseFromString(markup, 'image/svg+xml');
  const docEl = document.adoptNode(doc.documentElement); parent.appendChild(docEl);
}
// append a first version
appendSVGDoc(svg, document.body);
onclick = e => {
  // let's do some modifs
  document.getElementById('rect1').setAttribute('fill', 'yellow');
  onclick = e => {
    // append an other one
    appendSVGDoc(svg, document.body);
    // guess what color is the rect here?
  };
};
<p>click to modify the svg element.</p>
<p>click again to add a new copy of the original svg</p>

另一个例子?如果您的svg文档包含样式表,则此样式表的规则将影响整个文档:

const svg = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="500" height="200">
  <style>
    :root {
      font: 40px Serif;
    }
    rect {
      fill: green;
    }
  </style>
  <text y="50">I'm a big text in an svg image.</text>
  <rect x="25" y="75" width="50" height="50"/>
</svg>`;

function appendSVGDoc(markup, parent) {
  const doc = (new DOMParser).parseFromString(markup, 'image/svg+xml');
  const docEl = document.adoptNode(doc.documentElement); parent.appendChild(docEl);
}
onclick = e => {
  appendSVGDoc(svg, document.body);
};
<p>I am a simple html text content, and here is a simple svg &lt;rect> that should be red: <svg width="50" height="50"><rect x="0" y="0" height="50" width="50" fill="red"/></svg></p>

<p> click to append the external SVG </p>

因此,为避免此类情况,我只能建议您实际将svg文档加载到