Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Push SVG String into Dom?

Tags:

javascript

svg

I have a javascript variable that basically looks like this:

my_svg_image = '<circle cx="227.58331298828125" cy="102" r="3" style="fill:black;stroke-width:0" />';

It was loaded from my database. Is there a way I can parse that string and add it to the DOM with Javascript? I have svgweb set up, but don't see how I can get it to parse this string. Are there other libraries that might help?

like image 927
Colin Avatar asked Oct 14 '22 04:10

Colin


2 Answers

have you tried javascript's innerHTML property?

edit: You can only use innerHTML property for html elements, so you can use a string containing a whole svg image to add it to an html element. But you cannot add a svg element to an existing svg element.

Example:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
"http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg">
   <head>
      <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8"/>
   <script type="text/javascript">
   <![CDATA[    
    function test() {
        var newsvg = document.getElementById("svg-wrapper");
        var svgstr = '<svg:svg height="300" width="700" id="svg-container"><svg:circle cx="150px" cy="100px" r="30px" /></svg:svg>';
        newsvg.innerHTML = svgstr;
    }   
   ]]>
   </script>
   <title>SVG DOM</title>
 </head>
 <body>
    <div id="svg-wrapper"></div>
    <input type="button" onclick="javascript:test();" value="generate svg"/><br/>
 </body>
 </html>

If you want to add a circle to existing inline SVG, you have to add it using DOM methods (and the prbably first parse your string to extract the needed attribute values).

like image 69
räph Avatar answered Oct 20 '22 15:10

räph


I was recently looking for something similar to this, but I needed to update part of an existing SVG, so using innerHTML wasn't an option for me. I ended up taking a look at how Canvg pulls it off and came up with this:

var $contentToReplace = $('svg .some-class');
$contentToReplace.empty();

var content = new DOMParser().parseFromString(newContent, 'text/xml');

// content.children is an HTMLCollection, so using Array.prototype.slice to make a copy. if you
// don't make a copy, items will be removed from content.children each time appendChild is called,
// which will mess up the loop iteration
var children = Array.prototype.slice.call(content.children);
for (var i = 0; i < children.length; i++) {
  $contentToReplace.get(0).appendChild(children[i]);
}

You can check out how they did it in Canvg - just search for the parseXml method.

You can also pass in different MIME types to the parseFromString method. The browser support on those varies a bit though - for example, the 'image/svg+xml' MIME type isn't supported in IE9 or earlier.

Changing the MIME type just changes what type of document you get back. Using 'text/xml' gives back an XMLDocument, which appears to work fine in this case.

like image 23
dmccabe Avatar answered Oct 20 '22 17:10

dmccabe