12

I have a <div> that contains an inline svg. I would like a function that opens that svg in a new tab/window. I only want to use the front-end js without having to save the svg anywhere.

If I use window.open(), it puts the svg inside an <html> tag which I'm trying to avoid.

I'm basically trying to change this answer but then only have the svg code left: https://stackoverflow.com/a/21667339/1083923

//---print button---
    var printSVG = function()
    {
        var popUpAndPrint = function()
        {
            var container = $('#svgDiv');
            var width = parseFloat(container.getAttribute("width"))
            var height = parseFloat(container.getAttribute("height"))
            var printWindow = window.open('', 'PrintMap',
            'width=' + width + ',height=' + height);
            printWindow.document.writeln($(container).html());
            printWindow.document.close();
            printWindow.print();
            printWindow.close();
        };
        setTimeout(popUpAndPrint, 500);
    };
voloshin
  • 536
  • 7
  • 17
BelgoCanadian
  • 893
  • 1
  • 11
  • 31

1 Answers1

19

You can stringify your element into a valid SVG document and store it as a Blob, then point your new Window to that Blob using a blob:// URI:

// we need to handle a user gesture to use 'open'
document.getElementById("btn").onclick = (evt) => {
  // grab your svg element
  const svg = document.querySelector("svg");
  // convert to a valid XML source
  const as_text = new XMLSerializer().serializeToString(svg);
  // store in a Blob
  const blob = new Blob([as_text], { type: "image/svg+xml" });
  // create an URI pointing to that blob
  const url = URL.createObjectURL(blob);
  const win = open(url);
  // so the Garbage Collector can collect the blob
  win.onload = (evt) => URL.revokeObjectURL(url);
};

JS-fiddle demo since StackSnippet's sand-boxed iframes don't allow opening new windows.

Kaiido
  • 123,334
  • 13
  • 219
  • 285