Reputation: 3692
I have a SVG in my document and I add a symbol to it with JavaScript like this:
var myScene =document.getElementById('myScene');
var useSVG = document.createElement('use');
useSVG.setAttribute('xlink:href','spriteSheet.svg#mySymbol');
useSVG.setAttribute('x','10');
useSVG.setAttribute('y','30');
useSVG.setAttribute('width','10');
useSVG.setAttribute('height','10');
myScene.appendChild(useSVG);
The symbol does not show up whereas the resulting code is exactly the same as another node written in HTML which is displayed correctly.
Code shown in debugger:
<svg id="myScene" width="200px" height="200px">
<use xlink:href="spriteSheet.svg#mySymbol" x="5" y="50" width="10" height="10"></use>
<!-- this one was in html, it is visible -->
<use xlink:href="spriteSheet.svg#mySymbol" x="10" y="30" width="10" height="10"></use>
<!-- this one is added with javascript. it is not displayed -->
</svg>
Upvotes: 13
Views: 3007
Reputation: 61
I had exactly the same problem and I just figured it out! When creating the svg element with document.createElement("svg")
, you just have to use the correct namespace.
And it works even with other elements like path, line, rect etc
So this
document.createElement("svg");
Becomes that
document.createElementNS("http://www.w3.org/2000/svg","svg");
And this
document.createElement("use");
Becomes that
document.createElementNS("http://www.w3.org/2000/svg","use");
In case you wondering, you don't have to use element.setAttributeNS
, element.setAttribute
will work
Upvotes: 1
Reputation: 114
In general, to create SVG elements you must use createElementNS(), not createElement(). But even then, createElementNS() won't properly create an SVG "use" element. It appears to work, but the resulting "use" won't be displayed.
Workaround 1: clone an existing "use" element, then modify it via setAttributeNS(). (In my experience, setAttribute() also works on SVG elements.)
var useSVG = another_useSVG.cloneNode(true);
myScene.appendChild(useSVG);
useSVG.setAttribute('xlink:href','spriteSheet.svg#mySymbol');
Workaround 2: create a group element, then assign it's innerHTML to get the desired "use" element.
var myScene = document.getElementById('myScene');
var group = document.createElementNS('http://www.w3.org/2000/svg', 'g');
group.innerHTML = "<use xlink:href='spriteSheet.svg#mySymbol' x='10' y='30' width='10' height='10'/>";
Upvotes: 0
Reputation: 101938
You need to use createElementNS()
to create SVG elements. The basic createElement()
creates elements in the HTML namespace. So you basically have been creating <html:use>
elements instead of <svg:use>
ones.
var myScene =document.getElementById('myScene');
var useSVG = document.createElementNS('http://www.w3.org/2000/svg', 'use');
useSVG.setAttributeNS('http://www.w3.org/1999/xlink','href','spriteSheet.svg#mySymbol');
useSVG.setAttribute('x','10');
useSVG.setAttribute('y','30');
useSVG.setAttribute('width','10');
useSVG.setAttribute('height','10');
myScene.appendChild(useSVG);
Update
I have just realised there is a second problem with your code. You are using an external reference in your href
(it's referenceing a symbol in another file). It seems IE doesn't support external references.
I found more info, and a possible workaround, here: http://css-tricks.com/svg-use-external-source/
Upvotes: 19
Reputation: 16505
I am not sure to 100% but I think you need to set the xlink:href
Attribute using setAttributeNS()
like this:
useSVG.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', 'spriteSheet.svg#mySymbol');
Also make sure that the namespace is declared within your document.
<html xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- or if standalone svg -->
<svg xmlns:xlink="http://www.w3.org/1999/xlink">
However, this way I solved the same issue within an xhtml document, probably that will work for html5 or standalone SVG, too.
good luck!
Upvotes: 3