1

When I add this SVG in the HTML it displays. When I try to build it using JS it does not display. They code appears identical, obviously I have overlooked something.

In HTML works

<div><svg><use href="#star"></use></svg></div>

<svg xmlns="http://www.w3.org/2000/svg" >
    <symbol id='star' viewBox='0 0 460 460'>
        <style>.a{fill:#64C37D;}</style><polygon points="243.3 280.1 199.6 257.1 199.6 289.1 199.6 289.1 199.8 289.2 280.8 331.8 280.7 331.7 280.8 331.8 265.4 241.1 235 231.5 " fill="#99EFF2"/><polygon points="240.3 164 331 177.3 265.4 241.1 299.7 252.3 299.7 252.3 299.7 252.3 399.6 154.9 261.5 134.9 240.3 164 " fill="#933EC5"/><polygon points="299.7 252.3 265.4 241.1 280.8 331.8 280.7 331.7 280.8 331.8 199.8 289.2 199.8 324.9 199.8 324.9 323.2 389.8 323.2 389.7 323.2 389.8 " fill="#00D7DF"/><polygon points="199.8 289.2 199.6 289.1 118.3 331.8 133.8 241.3 133.7 241.2 99.9 252.2 99.9 252.3 99.9 252.3 76.3 389.8 199.8 324.9 199.8 324.9 " class="a"/><polygon points="99.9 252.2 133.7 241.2 68.1 177.3 68.2 177.2 68.2 177.2 159.3 164 159.3 164 138.1 134.8 138.1 134.8 0.1 154.9 0.1 154.9 0 154.9 99.9 252.3 99.9 252.3 " fill="#FF9811"/><polygon points="159.3 164 199.6 81.8 240.3 164 261.5 134.9 199.8 9.8 138.1 134.8 138.1 134.8 " fill="#EA348B"/><polygon points="133.9 241.2 164.1 231.5 164.1 231.4 " class="a"/><polygon points="331 177.3 240.3 164 221.6 189.8 270.4 196.8 235 231.5 265.4 241.1 " fill="#7C84E8"/><polygon points="199.6 257.1 199.5 257.1 155.8 280.1 164.1 231.5 133.9 241.2 133.9 241.3 133.8 241.3 118.3 331.8 199.6 289.1 199.6 289.1 " fill="#91DC5A"/><polygon points="133.9 241.2 164.1 231.4 128.7 196.8 177.7 189.6 159.3 164 159.3 164 68.2 177.2 68.2 177.2 68.1 177.3 133.7 241.2 133.8 241.3 133.9 241.3 " fill="#FFDA44"/><polygon points="177.7 189.6 199.6 145.4 221.6 189.8 240.3 164 240.3 164 199.6 81.8 159.3 164 159.3 164 159.3 164 " fill="#F7AED1"/>
    </symbol>
</svg>

IN JS does not work

c = {
'Make Bed': true, 
'Clean Room': true, 
'Study': false}

for (const i in c) {
        let cDiv = document.createElement('div')
        let cSvg = document.createElement('svg')
        cDiv.appendChild(cSvg)
        let cUse = document.createElement('use');
        if (c[i]) {
            cUse.setAttribute('href', '#star');  
        }
        cSvg.appendChild(cUse)
        document.querySelector('.container').appendChild(cDiv)
    }
royca
  • 27
  • 5

1 Answers1

3

In order to create SVG elements you have to use createElementNS. To set an attribute you need to use setAttributeNS where NS stands for namespace. Also you need to use the namespace URI

const SVG_NS = 'http://www.w3.org/2000/svg';
const SVG_XLINK = "http://www.w3.org/1999/xlink";



let cDiv = document.createElement('div');

let cSvg = document.createElementNS(SVG_NS, 'svg');
cDiv.appendChild(cSvg);
let cUse = document.createElementNS(SVG_NS, "use");
cUse.setAttributeNS(SVG_XLINK, "xlink:href", "#star");
cSvg.appendChild(cUse);
document.querySelector(".container").appendChild(cDiv);
svg{border:1px solid; max-width:100vh;}
<div class="container">
<div><svg><use href="#star"></use></svg></div>

<svg xmlns="http://www.w3.org/2000/svg" >
    <symbol id='star' viewBox='0 0 460 460'>
        <style>.a{fill:#64C37D;}</style><polygon points="243.3 280.1 199.6 257.1 199.6 289.1 199.6 289.1 199.8 289.2 280.8 331.8 280.7 331.7 280.8 331.8 265.4 241.1 235 231.5 " fill="#99EFF2"/><polygon points="240.3 164 331 177.3 265.4 241.1 299.7 252.3 299.7 252.3 299.7 252.3 399.6 154.9 261.5 134.9 240.3 164 " fill="#933EC5"/><polygon points="299.7 252.3 265.4 241.1 280.8 331.8 280.7 331.7 280.8 331.8 199.8 289.2 199.8 324.9 199.8 324.9 323.2 389.8 323.2 389.7 323.2 389.8 " fill="#00D7DF"/><polygon points="199.8 289.2 199.6 289.1 118.3 331.8 133.8 241.3 133.7 241.2 99.9 252.2 99.9 252.3 99.9 252.3 76.3 389.8 199.8 324.9 199.8 324.9 " class="a"/><polygon points="99.9 252.2 133.7 241.2 68.1 177.3 68.2 177.2 68.2 177.2 159.3 164 159.3 164 138.1 134.8 138.1 134.8 0.1 154.9 0.1 154.9 0 154.9 99.9 252.3 99.9 252.3 " fill="#FF9811"/><polygon points="159.3 164 199.6 81.8 240.3 164 261.5 134.9 199.8 9.8 138.1 134.8 138.1 134.8 " fill="#EA348B"/><polygon points="133.9 241.2 164.1 231.5 164.1 231.4 " class="a"/><polygon points="331 177.3 240.3 164 221.6 189.8 270.4 196.8 235 231.5 265.4 241.1 " fill="#7C84E8"/><polygon points="199.6 257.1 199.5 257.1 155.8 280.1 164.1 231.5 133.9 241.2 133.9 241.3 133.8 241.3 118.3 331.8 199.6 289.1 199.6 289.1 " fill="#91DC5A"/><polygon points="133.9 241.2 164.1 231.4 128.7 196.8 177.7 189.6 159.3 164 159.3 164 68.2 177.2 68.2 177.2 68.1 177.3 133.7 241.2 133.8 241.3 133.9 241.3 " fill="#FFDA44"/><polygon points="177.7 189.6 199.6 145.4 221.6 189.8 240.3 164 240.3 164 199.6 81.8 159.3 164 159.3 164 159.3 164 " fill="#F7AED1"/>
    </symbol>
</svg>

</div>
enxaneta
  • 31,608
  • 5
  • 29
  • 42
  • OK that resolved the issue thank you. Why do the SVG and USE elements require a namespace and why only in the javascript? – royca Oct 20 '18 at 12:35
  • Short answer: Creating elements named "svg" and "use" in an HTML document without setting a namespace just creates HTMLUnknownElement objects with those names. Long answer: please read [Namespaces Crash Course](https://developer.mozilla.org/en-US/docs/Web/SVG/Namespaces_Crash_Course) – enxaneta Oct 20 '18 at 12:44
  • the "short answer"above is a quote from [Using SVG with CSS3 and HTML5: Vector Graphics for Web Design](https://www.amazon.com/Using-SVG-CSS3-HTML5-Graphics/dp/1491921978/ref=sr_1_1?ie=UTF8&qid=1540039690&sr=8-1&keywords=amelia+bellamy-royds) – enxaneta Oct 20 '18 at 12:48