【问题标题】:Creating an SVG DOM element from a String从字符串创建 SVG DOM 元素
【发布时间】:2022-05-04 14:40:41
【问题描述】:

我将如何从String 创建一个 SVG DOM 元素?

例子:

var svgStr = '<svg width="500" height="400" xmlns="http://www.w3.org/2000/svg"><!-- Created with Method Draw - http://github.com/duopixel/Method-Draw/ --><g><title>background</title><rect fill="#fff" id="canvas_background" height="402" width="502" y="-1" x="-1"/><g display="none" overflow="visible" y="0" x="0" height="100%" width="100%" id="canvasGrid"><rect fill="url(#gridpattern)" stroke-width="0" y="0" x="0" height="100%" width="100%"/></g></g><g><title>Layer 1</title><path id="svg_1" d="m118,242l64,-153l63,157c0,0 45,-71 49,-68c4,3 11,146 12,146c1,0 -173,-7 -173,-7c0,0 -61,-72 -61,-72c0,0 110,-156 46,-3z" fill-opacity="0.7" stroke-width="2" stroke="#995757" fill="#995757"/></g></svg>';

【问题讨论】:

  • 那是什么语言? (var 不是 SVG 或 XML 的一部分;它是 JavaScript 吗?其他语言?)请编辑您的问题并添加正确的标签。
  • @helderdarocha 刚刚做了,抱歉。它在 JavaScript 中
  • 我发布了一个可能的答案。您可以在 JSFiddle 中尝试一下。

标签: javascript svg


【解决方案1】:

您可以使用DOMParser 来解析 XML 字符串。

var parser = new DOMParser();
var doc = parser.parseFromString(stringContainingXMLSource, "image/svg+xml");

解析后的字符串的根元素是 doc.documentElement

为了让它在跨浏览器中正常工作,你需要设置 html 命名空间,即你的字符串需要看起来像这样......

var svg2='<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" ...

【讨论】:

  • 在我的例子中,使用 DOM Parser 使 SVG 的渲染变得非常缓慢和滞后。我尝试附加 SVG(不是作为字符串)并且没有性能问题。这里面有什么资料吗?另外,IE对此的支持如何?
  • 单独提出新问题,尽管 FWIW IE 确实支持这一点。
【解决方案2】:

假设您使用的是 JavaScript,您可以简单地将字符串作为通过 DOM API 获得的现有元素的 innerHTML 传递:

var svg2 = "<svg ...> ... </svg>";
var container = document.getElementById("container");
container.innerHTML = svg2;

请参阅:JSFiddle

【讨论】:

  • 我不确定 IE 以前的版本,但它肯定可以在当前版本中工作(我无法测试它,因为我在 Mac 中)。它也适用于 Firefox 29.0.1、Chrome 35.0 和 Opera 22.0。
  • 但要小心,因为执行.innerHTML += 会清除您在innerHTML 中的元素上可能拥有的所有事件侦听器。我花了很长时间调试才弄明白。
  • 小心不要打开您的应用程序受到 DOM XSS 攻击——请参阅web.dev/trusted-types/#rewrite-the-offending-code
【解决方案3】:

我正在构建 SVG 图表,需要使用户能够传递任何 SVG 以使其成为图表注释。解决方案是:

index.html - 我将子 SVG 附加到的根 SVG 元素

<svg id="chart_SVG" width="900" height="600" role="img" xmlns="http://www.w3.org/2000/svg"></svg>

api.ts - 添加注释的 API(用 TypeScript 编写)。 x, y - 放置注释的坐标

function drawAnnotation(x: number, y: number, svgContent: string, svgId: string): SVGElement {
  const svgRoot = document.getElementById("chart_SVG");
  const svgNode = document.createRange().createContextualFragment(svgString);
  svgRoot.appendChild(svgNode);
  const newNode = this.svgRoot.lastChild as SVGElement;
  newNode.id = svgId;
  newNode.setAttribute("x", x.toString());
  newNode.setAttribute("y", y.toString());
  return newNode;
}

example.ts

drawAnnotation(
  100,
  100,
  '<svg><g><rect x="0" y="0" width="100%" height="100%" stroke="red" stroke-width="10" fill="orange"/><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-family="Verdana" font-size="24" fill="blue">TEXT</text></g></svg>',
  "myNewNode"
)

【讨论】:

    【解决方案4】:

    在 HTML 中读取和写入 SVG 的 innerHTML 似乎运行良好,但在 Internet Explorer (9-11) 中除外:http://cs.sru.edu/~ddailey/svg/IframeSVG.htm。如果需要 IE 兼容性(如在真正的 Web 应用程序中),则使用 DOM 方法创建合适的容器(对象、iframe 或嵌入)并通过该容器中的 DOM 方法构建 SVG,一次一个 childNode。 ) 这有点麻烦,但http://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#SVG_HTML 涵盖了基础知识。

    【讨论】:

      【解决方案5】:

      这是一个返回SVGELement实例的JS函数示例:

      function svgElementFromString(str: string): SVGElement {
          const div = document.createElement('DIV');
          div.innerHTML = str;
          const svg = div.querySelector('svg') as SVGElement;
      
          if (!svg) {
            throw Error('<svg> tag not found');
          }
      
          return svg;
        }
      

      【讨论】:

        猜你喜欢
        • 2020-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-10
        • 2010-10-04
        • 2012-01-09
        • 1970-01-01
        相关资源
        最近更新 更多