Search code examples
javascripthtmlsvg

Why does my directly created SVG show up, yet my identical dynamically created SVG does not show up below it?


I am wanting to move into dynamically creating SVG elements.

I have the following HTML file:

<!DOCTYPE html><html><head>
<script>
var d=document,ns="http://www.w3.org/2000/svg";
window.onload = S;

function S() {
var bo=d.body;
var div=C(bo,'div');
A(div,'style','width:50vw;height:50vw;');
div.innerHTML="The second (dynamically created) svg does not show up!:"
var svg=Cn(div,'svg');
A(svg,'xmlns','http://www.w3.org/2000/svg');//An(...) gives error if used
An(svg,'viewbox','0 0 22 22');
An(svg,'style','width:40vw;height:40vw;');
var path=Cn(svg,'path');
An(path,'stroke','grey');
An(path,'d','M2 16c-4-2,0-10,4-8c3-12,24 8,12 8z');
}

function C(x,y){var z=d.createElement(y);x.appendChild(z);return z;}
function Cn(x,y){var z=d.createElementNS(ns,y);x.appendChild(z);return z;}
function A(x,y,z){x.setAttribute(y,z);}
function An(x,y,z){x.setAttributeNS(ns,y,z);}

</script></head>
<body>
<div style="width:50vw;height:50vw;">
The first svg here shows correctly:
<svg  xmlns="http://www.w3.org/2000/svg" viewbox="0 0 22 22" style="width:40vw;height:40vw;">
<path stroke="grey" d="M2 16c-4-2,0-10,4-8c3-12,24 8,12 8z"></path></svg></div>
</html>

This is a real puzzle because the DOM elements for BOTH SVGs are showing up as IDENTICAL in dev tools: Dev tools I've tried numerous combinations of with/without SVG namespace, and other things for days and can't solve it. Any help would be appreciated.


Solution

  • You don't need to explicitly set the namespace for the attributes, and you had a typo in viewBox:

    var d = document,
      ns = "http://www.w3.org/2000/svg";
    window.onload = S;
    
    function S() {
      var bo = d.body;
      var div = C(bo, 'div');
      A(div, 'style', 'width:50vw;height:50vw;');
      div.innerHTML = "The second svg does too!:"
      var svg = Cn(div, 'svg');
      A(svg, 'xmlns', 'http://www.w3.org/2000/svg');
      A(svg, 'viewBox', '0 0 22 22');
      A(svg, 'style', 'width:40vw;height:40vw;');
      var path = Cn(svg, 'path');
      A(path, 'stroke', 'grey');
      A(path, 'd', 'M2 16c-4-2,0-10,4-8c3-12,24 8,12 8z');
    }
    
    function C(x, y) {
      var z = d.createElement(y);
      x.appendChild(z);
      return z;
    }
    
    function Cn(x, y) {
      var z = d.createElementNS(ns, y);
      x.appendChild(z);
      return z;
    }
    
    function A(x, y, z) {
      x.setAttribute(y, z);
    }
    
    function An(x, y, z) {
      x.setAttributeNS(ns, y, z);
    }
    <div style="width:50vw;height:50vw;">
      The first svg here shows correctly:
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 22" style="width:40vw;height:40vw;">
        <path stroke="grey" d="M2 16c-4-2,0-10,4-8c3-12,24 8,12 8z"/>
      </svg>
    </div>