Search code examples
javascriptsvgmobile-safarisnap.svg

Can't read SVG element contents in mobile Safari with Javascript


To reuse certain SVG objects I have symbols defined in an SVG element which is written out at the top of my DOM. To display an SVG I can do:

<svg><use xlink:href="#symbol-identifier" /></svg>

To animate some SVG's I use Snap.svg, but I can't seem to create a Snap object from an SVG referenced by an xlink. To work around this I want to inject the SVG contents (already present in the DOM) at runtime into the SVG currently using the xlink.

To do this I need to get the contents (innerHTML?) of a symbol. This works in every browser i tested, except for mobile safari.

Below a simple test setup (without the symbol-wrap, but works the same):

HTML:

<div id="outer" style="width: 100px; height: 100px;">
    <svg id="inner" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg">
        <circle cx="10" cy="10" r="5" fill="#ffffff" />
    </svg>
</div>

Javascript:

var outerElement = document.getElementById('outer');
var innerElement = document.getElementById('inner');

outerElement.innerHTML // returns <svg id=".. etc..
innerElement.toString() // returns [object SVGSymbolElement]
innerElement.getAttribute('viewBox') // returns 0 0 100 100
innerElement.innerHTML // returns undefined (in Mobile Safari)
// Everywhere else the content <circle .. etc .. is returned.

Why is this? And is there another way of getting the SVG contents as a string, without regexping away all the unwanted HTML around the outerElement.


Solution

  • XMLSerializer can serialize elements.

    var string = XMLSerializer().serializeToString(innerElement);
    

    should work for you.