42

Say you have this in your HTML:

<img src='example.svg' />

How would you access the contents ( ie. <rect>, <circle>, <ellipse>, etc.. ) of the example.svg via JavaScript?

user783146
  • 1,511
  • 3
  • 12
  • 6

5 Answers5

42

It's not possible to get the DOM of a referenced svg from the img element.

If you use <object>, <embed> or <iframe> however then you can use .contentDocument (preferred) to get the referenced svg, or .getSVGDocument which may be more compatible with old svg plugins.

Here's an example showing how to get the DOM of a referenced svg.

Erik Dahlström
  • 59,452
  • 12
  • 120
  • 139
  • is the link to the example broken ? – Goswin Rothenthal Dec 04 '15 at 10:24
  • @Goswin odd, looks like a web server glitch, the files are there... hopefully it'll start working soon. – Erik Dahlström Dec 04 '15 at 12:38
  • 3
    Note that `.contentDocument` can access an external SVG file referenced by `` and ` – Andrew Willems Mar 07 '16 at 06:58
  • 1
    Anyone needing to use the `` tag (e.g. if you don't have control over the SVG resource) may want to know about appending [SVG Fragement identifiers](https://www.w3.org/TR/SVG/linking.html#SVGFragmentIdentifiers), e.g. "``", which lets you control the aspect ratio, `viewBox`, etc the same as with inline SVG definitions. – brichins Jun 16 '16 at 17:06
  • document.querySelector('#id-of-object-containing-svg').contentDocument.querySelector('svg').outerHTML – A2D Sep 30 '18 at 11:42
17

I'm pretty sure this isn't possible. The external SVG is not part of the DOM in the way an inline SVG is, and I don't believe you can access the SVG DOM tree from the loading document.

What you can do is load the SVG as XML, using an AJAX request, and insert it into the DOM as an inline SVG you can then walk and manipulate. This D3 example demonstrates the technique. I think the d3.xml() function used here is more or less equivalent to jQuery's $.ajax() with dataType: "xml".

nrabinowitz
  • 55,314
  • 10
  • 149
  • 165
  • 7
    That or use an ``, `` or ` – Erik Dahlström Nov 13 '11 at 14:54
  • Really? I'm playing around with it a little bit, and neither jQuery nor `element.childNodes` seem to show any exposed SVG DOM. Do you have an example? – nrabinowitz Nov 14 '11 at 03:00
  • 1
    Examples: http://xn--dahlstrm-t4a.net/svg/html/get-embedded-svg-document-script.html – Erik Dahlström Nov 14 '11 at 07:24
  • 3
    Thanks, that's very cool - had never heard of `getSVGDocument`. You should submit as an answer - I think it's a simpler and more straightforward method than mine. – nrabinowitz Nov 15 '11 at 03:43
  • nrabinowitz: Agreed, Erik Dahlstroms example here is a great solution - you get bounty points by proxy! – A2D Jul 05 '16 at 17:57
  • this question has a very popular answer for how to convert an img which is SVG to an SVG inline http://stackoverflow.com/questions/11978995/how-to-change-color-of-svg-image-using-css-jquery-svg-image-replacement – Simon_Weaver Oct 01 '16 at 02:27
2

No, not possible but you can convert <img> to <svg> as mentioned HERE (same code available below) and you can access the nodes of svg in the DOM.

<script type="text/javascript">

    $(document).ready(function() {
        $('#img').each(function(){
            var img         = $(this);
            var image_uri   = img.attr('src');

            $.get(image_uri, function(data) {
                var svg = $(data).find('svg');
                svg.removeAttr('xmlns:a');
                img.replaceWith(svg);
            }, 'xml');

        });
    });
</script>


<img id='img' src="my.svg" />
Syed
  • 15,657
  • 13
  • 120
  • 154
1

If you are using inlining of SVG into CSS url(data:...) or just using url(*.svg) background, you can embed them into DOM with svg-embed.

Support Chrome 11+, Safari 5+, FireFox 4+ and IE9+.

Anton Medvedev
  • 3,393
  • 3
  • 28
  • 40
0

If you’re using a back end language that can go fetch the file and insert it, at least you can clean up the authoring experience. Like:

<?php echo file_get_contents("kiwi.svg"); ?>

A little PHP-specific thing here… it was demonstrated to me that file_get_contents() is the correct function here, not include() or include_once() as I have used before. Specifically because SVG sometimes is exported with that as the opening line, which will cause the PHP parser to choke on it.

(Information taken out of CSS-tricks)

jDelforge
  • 129
  • 4
  • 15