The simplest way to understand creating and modifying SVG elements is to operate on the elements using the DOM Level 2 Core interfaces, as you would with HTML or XML.
It is imperative that the elements created from JavaScript are created in the same namespace declared in the SVG element - in this example: "http://www.w3.org/2000/svg". However, almost all attributes of SVG elements are not in any namespace. You must not place them in the SVG namespace.
Here we demonstrate SVG hosted inside of HTML, as this is a common case:
<!doctype HTML>
<html><title>Creating an Element</title>
<body>
<svg xmlns="http://www.w3.org/2000/svg"
width="100%" height="100%"
viewBox="0 0 400 300"></svg>
<script>
var svgNS = "http://www.w3.org/2000/svg";
// Create a circle element (not part of the DOM yet)
var circle = document.createElementNS(svgNS,'circle'); // Creates a <circle/>
circle.setAttribute('fill','red'); // Note: NOT setAttributeNS()
circle.setAttribute('cx',150); // setAttribute turns 150 into a string
circle.setAttribute('cy','80'); // using a string works, too
circle.setAttribute('r',35); // give the circle a radius so we can see it
// Now, add the circle to the SVG document so we can see it
var svg = document.querySelector('svg'); // the root <svg> element
svg.appendChild(circle);
</script>
</body></html>
There are a few attributes that need to be created in a particular namespace. They are the ones listed with colons in their names in the SVG Attribute Index. Specifically, they are: xlink:actuate
, xlink:arcrole
, xlink:href
, xlink:role
, xlink:show
, xlink:title
, xlink:type
, xml:base
, xml:lang
, and xml:space
. Set these attributes using setAttributeNS()
:
var svgNS = "http://www.w3.org/2000/svg";
var xlinkNS = "http://www.w3.org/1999/xlink";
var img = document.createElementNS( svgNS, 'image' );
img.setAttributeNS( xlinkNS, 'href', 'my.png' );
If you are creating elements often, particularly with many attributes, a helper function like the following can save you typing, avoid mistakes, and make your code easier to read:
<!doctype HTML>
<html><title>Creating an Element</title>
<body>
<svg xmlns="http://www.w3.org/2000/svg"></svg>
<script>
var svg = document.querySelector('svg');
var circle = createOn( svg, 'circle', {fill:'red', cx:150, cy:80, r:35} );
// Create an SVG element on another node with a set of attributes.
// Attributes with colons in the name (e.g. 'xlink:href') will automatically
// find the appropriate namespace URI from the SVG element.
// Optionally specify text to create as a child node, for example
// createOn(someGroup,'text',{x:100,'text-anchor':'middle'},"Hello World!");
function createOn(parentEl,name,attrs,text){
var doc=parentEl.ownerDocument, svg=parentEl;
while (svg && svg.tagName!='svg') svg=svg.parentNode;
var el = doc.createElementNS(svg.namespaceURI,name);
for (var a in attrs){
if (!attrs.hasOwnProperty(a)) continue;
var p = a.split(':');
if (p[1]) el.setAttributeNS(svg.getAttribute('xmlns:'+p[0]),p[1],attrs[a]);
else el.setAttribute(a,attrs[a]);
}
if (text) el.appendChild(doc.createTextNode(text));
return parentEl.appendChild(el);
}
</script>
</body></html>