1

I'm drawing some SVG inline with JavaScript. Mostly paths, though I did also try a polygon. I manage to populate a <svg> tag with paths (one in this simplified example) that are correct SVG. I know this because:

  1. When the contents of the svg tag are copied in to a file and opened in Inkscape, the resulting picture is as expected.
  2. If I change a <path> in Firefox's Inspector in some way, like removing the </path> end tag, (which just causes Firefox to repair the code to the way it originally was), that particular path will display, but the rest still won't.
  3. When I copy all the html in the page as it is after the javascript has run, and put that in a new html file, the svg displays correctly.

I originally ran into this problem in Firefox, but did also verify that the svg creation doesn't work in Edge either.

So how would I make the inline svg render immediately after it has been created?

EDIT: Not the same as this: JavaScript and SVG: Error on createElement(). That question pertains to an SVG document, not HTML. Also I don't get an error message at all.

<html>

<head></head>

<body>

  <svg id="drawing"></svg>

  <script>
    function creel(tagname, id, cla, attrs) {
      var n = document.createElement(tagname);
      if (id) {
        n.id = id;
      }
      if (cla) {
        n.className = cla;
      }
      if (attrs) {
        for (var i = 0; i < attrs.length; i = i + 2) {
          n.setAttribute(attrs[i], attrs[i + 1]);
        }
      }
      return n;
    }

    function drawline(c, ax, ay, bx, by, style) {
      // Method for svg
      var d = "M" + ax + "," + ay + " L" + bx + "," + by;
      var p = creel("path", "", "", ["d", d]);
      if (style) {
        p.setAttribute("style", style);
      } else {
        p.setAttribute("style", "stroke:#555555;stroke-width:2; fill:none;");
      }
      c.appendChild(p);
    }

    function drawit() {
      var c = document.getElementById("drawing");
      c.setAttribute("width", 500);
      c.setAttribute("height", 500);
      c.setAttribute("viewBox", "0 0 500 500");
      c.setAttribute("xmlns", "http://www.w3.org/2000/svg");
      c.setAttribute("style", "border-style:solid;border-width:1px;background:#eeeeee;");

      var thinstyle = "stroke:#555555;stroke-width:2; fill:none;";

      drawline(c, 10, 10, 400, 400, thinstyle);
    }



    window.onload = function() {
      drawit();
    }
  </script>
</body>

</html>
  • It makes no difference whether you're working with an SVG document or an HTML document, you can't use createElement to create SVG elements. No you won't get an error message as using createElement is not a syntax error. – Robert Longson Sep 28 '17 at 04:51

1 Answers1

3

Create SVG elements with Document.createElementNS

When creating straight from JavaScript, you need to create svg elements with Document.createElementNS:

 var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');

Your example rendering the path:

function creel(tagname, id, cla, attrs) {
  // USE createElementNS HERE
  var n = document.createElementNS('http://www.w3.org/2000/svg', tagname);
  if (id) {
    n.id = id;
  }
  if (cla) {
    n.className = cla;
  }
  if (attrs) {
    for (var i = 0; i < attrs.length; i = i + 2) {
      n.setAttribute(attrs[i], attrs[i + 1]);
    }
  }
  return n;
}

function drawline(c, ax, ay, bx, by, style) {
  // Method for svg
  var d = "M" + ax + "," + ay + " L" + bx + "," + by;
  var p = creel("path", "", "", ["d", d]);
  if (style) {
    p.setAttribute("style", style);
  } else {
    p.setAttribute("style", "stroke:#555555;stroke-width:2; fill:none;");
  }
  c.appendChild(p);
}

function drawit() {
  var c = document.getElementById("drawing");
  c.setAttribute("width", 500);
  c.setAttribute("height", 500);
  c.setAttribute("viewBox", "0 0 500 500");
  c.setAttribute("xmlns", "http://www.w3.org/2000/svg");
  c.setAttribute("style", "border-style:solid;border-width:1px;background:#eeeeee;");

  var thinstyle = "stroke:#555555;stroke-width:2; fill:none;";

  drawline(c, 10, 10, 400, 400, thinstyle);
}

window.onload = function() {
  drawit();
}
<svg id="drawing"></svg>

Also, keep in mind that some attributes on SVG elements should/need to be set with the setAttributeNS method. One of the attributes that should be set with setAttributeNS is xmlns.

KevBot
  • 17,900
  • 5
  • 50
  • 68
  • Thanks! That worked for this simplified example as well as my actual website. I was guessing it might have something to do with namespaces, but I don't-didn't-really understand them at all. – Lauri Niskanen Sep 27 '17 at 21:14