简体   繁体   English

从字符串创建 SVG DOM 元素

[英]Creating an SVG DOM element from a String

How would I go about creating an SVG DOM element from a String ?我将如何 go 关于从String创建 SVG DOM 元素?

Example:例子:

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>';

You can use DOMParser to parse an XML string.您可以使用DOMParser来解析 XML 字符串。

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

The root element for the parsed string will be doc.documentElement解析字符串的根元素将是 doc.documentElement

For this to work properly cross-browser you'll need to set the html namespace ie your string will need to look like this...为了使其跨浏览器正常工作,您需要设置 html 命名空间,即您的字符串需要看起来像这样......

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

Assuming you are using JavaScript, you can simply pass that string as the innerHTML of an existing element obtained via the DOM API:假设您使用的是 JavaScript,您可以简单地将该字符串作为通过 DOM API 获得的现有元素的innerHTML传递:

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

See: JSFiddle请参阅: JSFiddle

Reading and writing the innerHTML of an SVG within HTML seems to work well except in Internet Explorer (9-11): http://cs.sru.edu/~ddailey/svg/IframeSVG.htm .除了 Internet Explorer (9-11): http : //cs.sru.edu/~ddailey/svg/IframeSVG.htm之外,在 HTML 中读取和写入 SVG 的 innerHTML 似乎工作得很好。 If one needs IE compatibility (as in for a real web app) then use DOM methods to create a suitable container (object, iframe or embed) and build the SVG, one childNode at a time, through DOM methods within that container.如果需要 IE 兼容性(如真正的 Web 应用程序),则使用 DOM 方法创建合适的容器(对象、iframe 或嵌入)并通过该容器中的 DOM 方法一次构建一个 childNode SVG。 ) It's a bit of a chore, but the basics are covered at http://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#SVG_HTML . ) 这有点麻烦,但基础知识在http://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#SVG_HTML 中有介绍。

I was building SVG chart and needed to enable user to pass any SVG to make it into a chart annotation.我正在构建 SVG 图表,需要使用户能够传递任何 SVG 以使其成为图表注释。 The solution was:解决方案是:

index.html - the root SVG element I am attaching child SVGs to 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 to add annotation (written in TypeScript). api.ts - 添加注释的 API(用 TypeScript 编写)。 x, y - coordinates where to place the annotation 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例子.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"
)

Here is a JS function example to return a SVGELement instance:这是一个返回SVGELement实例的 JS function 示例:

function svgElementFromString(str) {
    const div = document.createElement('DIV');
    div.innerHTML = str;
    const svg = div.querySelector('svg');

    if (!svg) {
      throw Error('<svg> tag not found');
    }

    return svg;
  }

instead of returning with parent, you can do the following trick.您可以执行以下技巧,而不是与父母一起返回。

const template = `
  <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M1 13L13 1M1 1L13 13" stroke="#111827" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
  </svg>`

  const span = document.createElement('span')
  span.innerHTML = template
  return span.firstChild

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM