Reputation: 310917
Consider the following chunk of SVG:
<defs>
<radialGradient id="gradient" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
<stop offset="0%" style="stop-color:#568f82;stop-opacity:1" />
<stop offset="100%" style="stop-color:#568f82;stop-opacity:0" />
</radialGradient>
</defs>
The corresponding JavaScript to create those elements is:
var defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
var radialGradient = document.createElementNS('http://www.w3.org/2000/svg', 'marker');
radialGradient.id = 'gradient';
radialGradient.setAttribute('cx', '50%');
radialGradient.setAttribute('cy', '50%');
radialGradient.setAttribute('fx', '50%');
radialGradient.setAttribute('fy', '50%');
radialGradient.setAttribute('r', '50%');
var stop1 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
stop1.setAttribute('offset', '0%');
stop1.setAttribute('style', 'stop-color:#568f82;stop-opacity:1');
radialGradient.appendChild(stop1);
var stop2 = document.createElementNS('http://www.w3.org/2000/svg', 'path');
stop2.setAttribute('offset', '100%');
stop2.setAttribute('style', 'stop-color:#568f82;stop-opacity:0');
radialGradient.appendChild(stop2);
defs.appendChild(radialGradient);
this.svgElement.appendChild(defs);
Is there a way of using the XML markup inline in the JavaScript? I've tried something resembling the following but without any luck:
var defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
defs.innerHTML =
'<radialGradient id="gradient" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">' +
' <stop offset="0%" style="stop-color:#568f82;stop-opacity:1" />' +
' <stop offset="100%" style="stop-color:#568f82;stop-opacity:0" />' +
'</radialGradient>';
It seems that innerHTML
is not a property of SVGElement
.
Upvotes: 0
Views: 187
Reputation: 22660
If you want even more concise syntax and you are willing to use libraries, consider trying Raphaël or svg.js.
Upvotes: 0
Reputation: 124059
var parser = new DOMParser();
var doc = parser.parseFromString(stringContainingXMLSource, "image/svg+xml");
Note that the parent node will need to have an explicit namespace so that it gets parsed correctly i.e. the String would need to look like this:
var stringContainingXMLSource = '<radialGradient xmlns="http://www.w3.org/2000/svg" id="gradient" ...
Then you can do
defs.appendChild(document.importNode(doc.documentElement));
Some UAs also allow doc.rootElement instead of doc.documentElement but apparently not all.
Upvotes: 2
Reputation: 536399
There isn't a direct markup property, but you can use DOMParser.parseFromString()
to parse some XML into a new SVG document and importNode
it across. Or, you can use innerHTML
to set the content of a container HTML element and pull the SVG nodes out of the result.
But string-slinging gets a bit mucky—as soon as you want to bring in variable content or attribute values, it's easy to do a string concatenation without remembering proper escaping, leading to cross-site-scripting problems. It's nice to be able to keep everything in a world of objects and properties rather than encoded markup when you can.
Admittedly the uber-verbose DOM API doesn't make that easy, but you can write shortcut functions to call the DOM methods for you, allowing you to write something like:
xml(SVG, 'defs', {}, [
xml(SVG, 'radialGradient', {id: 'gradient', cx: '50%', cy: '50%', fx: '50%', fy: '50%' r: '50%'}, [
xml(SVG, 'path', {offset: '0%', 'stop-color': '#568f82', 'stop-opacity': 1}),
xml(SVG, 'path', {offset: '100%', 'stop-color': '#568f82', 'stop-opacity': 0})
])
])
which is a lot easier to cope with.
Upvotes: 1