97

I have a HTML construction that resembles the following code:

<div id='intro'>
<svg>
//draw some svg elements
<svg>
</div>

I want to be able to add some elements to the SVG defined above using javascript and DOM. How would I accomplish that? I was thinking of

var svg1=document.getElementById('intro').getElementsByTagName('svg');
svg1[0].appendChild(element);//element like <line>, <circle>

I am not very familiar with using DOM, or how to create the element to be passed to appendChild so please help me out with this or perhaps show me what other alternatives I have to solve this issue. Thanks a lot.

biggdman
  • 2,028
  • 7
  • 32
  • 37

2 Answers2

220

If you want to create an HTML element, use document.createElement function. SVG uses namespace, that's why you have to use document.createElementNS function.

var svg = document.getElementsByTagName('svg')[0]; //Get svg element
var newElement = document.createElementNS("http://www.w3.org/2000/svg", 'path'); //Create a path in SVG's namespace
newElement.setAttribute("d","M 0 0 L 10 10"); //Set path's data
newElement.style.stroke = "#000"; //Set stroke colour
newElement.style.strokeWidth = "5px"; //Set stroke width
svg.appendChild(newElement);

This code will produce something like this:

<svg>
 <path d="M 0 0 L 10 10" style="stroke: #000; stroke-width: 5px;" />
</svg>



createElement: https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement

createElementNS: https://developer.mozilla.org/en-US/docs/Web/API/Document/createElementNS

Rvervuurt
  • 8,589
  • 8
  • 39
  • 62
m93a
  • 8,866
  • 9
  • 40
  • 58
  • 1
    I get `Uncaught TypeError: Cannot read property 'setAttribute' of null`. – B Seven Jan 06 '15 at 01:25
  • 1
    @Rvervuurt Hey, what are you doing with my post? :D – m93a Aug 18 '15 at 08:46
  • @m93a Removing unnecessary images. If you want to have fun with images, go to a forum or chat, here it just distracts :) – Rvervuurt Aug 18 '15 at 09:36
  • 4
    Why's this not drawing? oh yeah, the namespace: gets me every time. – Lucas Oct 13 '17 at 14:11
  • It should be noted that contrary to what one would think, you most use `newElement.setAttribute()` to set attribute as oppose to `newElement.setAttributeNS()` - at least in Chrome. – dotnetCarpenter May 24 '18 at 14:31
  • @dotnetCarpenter That's because `setAttributeNS` is for setting [namespaced attributes](https://stackoverflow.com/questions/41561/xml-namespaces-and-attributes). If you look at my answer, it's using `setAttribute`, not `setAttributeNS`. – m93a May 25 '18 at 16:27
  • I'm following this and using createElementNS for my path but it's not showing up on my page however, it shows in Dom when I inspect the page – BrunoElo May 30 '21 at 17:00
  • @BrunoElo Are you creating more elements than just ``? All SVG elements that you add to the DOM have to be namespaced, else they won't work. Also, double-check the namespace URL, it has to be exactly `http://www.w3.org/2000/svg` and nothing else. – m93a May 31 '21 at 13:36
  • Turns out I needed to create the svg element itself with createElementNS as done here https://stackoverflow.com/a/37079831/8265811 – BrunoElo Jun 01 '21 at 13:04
13

If you're dealing with svg's a lot using JS, I recommend using d3.js. Include it on your page, and do something like this:

d3.select("#svg1").append("circle");
ragingsquirrel3
  • 415
  • 3
  • 12
  • 49
    I would like to do it using plain javascript, without external libraries or functions – biggdman May 10 '13 at 19:03
  • 1
    I second the suggestion for using D3. If you're just doing a one-off, then yeah, write it in pure JavaScript. But if you do a lot of work with SVG's, then you're doing yourself a huge favor to switch over to d3.js. It's an incredibly lightweight library, too. And it does more than just SVG's; it actually converts the DOM to a database. It's just that it makes working with SVG's a snap, so it has become a _de facto_ SVG library. – Jonathan E. Landrum Sep 13 '21 at 15:57