Asynchronously Loading SVG

If you have some beautiful interactive SVG that you want to embed into your web page, the best option is generally to inline the SVG into the HTML itself.  Then you have access to the SVG DOM and can provide all the interactive behaviors you can dream up.  The problem is, if you have a large SVG file, your HTML quickly gets polluted with all of the SVG content.

Instead, one option is to load the SVG into the HTML asynchronously.  A simple way to do this with jQuery is with jQuery.load(), as in:

jQuery(selector).load(<URL to SVG> [, data ] 
        [, complete(responseText, textStatus, XMLHttpRequest) ]);

You can even use the complete() function to then add any interactivity not already baked into the SVG itself, something like:

jQuery('#svg-main').load('/wp-content/uploads/2013/02/piano.svg', null, function() { 
    jQuery('#theElement').click( function() {
        alert('You clicked on the element!');
    });
});

Take at the SVG below, a beautiful rendering of some of the inner workings of a piano.  If you look at the source for this page, the SVG was actually loaded asynchronously in this manner.  There is no inline SVG in this page.  But, do you see that thingamabob that the circle with the number 15 is pointing to?  Click on that and you should see an alert.  That was added after we asynchronously loaded the SVG.

You can also see separate demo showing off this demo outside of a WordPress page here.

Ya gotta love SVG.

Tagged , , . Bookmark the permalink.

9 Responses to Asynchronously Loading SVG

  1. Scott B says:

    Not sure if I’m missing anything here. The point of this is really just to keep the source document a little less cluttered because of the size of all the SVG markup?

    In which case, this is really more of a jQuery lesson than an SVG lesson. While load() is probably the shortest hand way of fetching your markup, there are multiple ways to fetch the data (which doesn’t just have to be SVG).

    $(‘#svg-content’).load(‘/wp-content/uploads/2013/02/piano.svg’, null, function() {
    $(‘#path7992′).click(function() {
    alert(‘You clicked the thingamabob!’);
    });
    });

    $.get(‘/wp-content/uploads/2013/02/piano.svg’, function(data) {
    $(‘#svg-content’).html(data);
    $(‘#path7992′).click(function() {
    alert(‘You clicked the thingamabob!’);
    });
    });

    $.ajax({
    url: ‘/wp-content/uploads/2013/02/piano.svg’,
    success: function(data) {
    $(‘#svg-content’).html(data);
    $(‘#path7992′).click(function() {
    alert(‘You clicked the thingamabob!’);
    });
    }
    });

    • agreenblatt says:

      Scott, you’re absolutely right. You’re not missing anything here. This wasn’t meant to be monumentally profound. You don’t even have to use jQuery to do this. It just makes your life easier, and in this case I wanted to keep the code to a minimum so as not to distract from the point I was trying to make.

      Rather, I was seeing many discussions about how best to embed SVG in HTML. Should you use inline SVG? What about using an Object tag? What about an IMG tag with the SVG as source? It seems that if you want interactive behavior, and want to be able to easily access the SVG DOM, then inline SVG is your best bet. But, then you end up with very messy HTML. And, if the SVG is large enough, you could slow down page loading. Though to be perfectly honest, I’m not sure how browsers deal with SVG content. My guess is that subsequent page loading & rendering could get blocked until all of the SVG is processed. By having the SVG load asynchronously, we can parallelize the page loading and give the user a better experience.

  2. As just an FYI, I needed to use $.get instead for reasons not important. I was passing the result of the get() to another function. When I tried to load this into the div via html() it failed. Why? Because jQuery was (properly) noticing that the result was XML and converting it into a proper XML object.

    To get around this, I made my get() use a third argument of “plain”. This left the string alone.

    • agreenblatt says:

      Absolutely, that makes sense. Another option with get() if you need both the XML and the string is to use the results in jqXHR returned with jQuery.get(). The success function takes 3 parameters: data, textStatus & jqXHR. jqXHR.responseXML returns the XML result while jqXHR.responseText returns the string that you could pass to html().

  3. Daniel says:

    Is it possible to do the same with just javascript and make it works on all latest browsers?

    I was successful in accessing the loaded SVG file with using the contentDocument on the IE browser.

    However, am still having problems with the Chrome browser, even with the getSVGDocument.

    In Chrome, I can load the SVG file into an “object” element, but can not figure out how to access the loaded SVG file.

    Would appreciate your advise.

    Thanks,
    Daniel

  4. Daniel says:

    Alan,
    Thanks for the recent response.

    We are building an application where the user can load dynamically different svg files, by selecting the specific file from a dropdown box.

    So far it is working ok on most browsers.
    We do, however, have problems with the default browser of the Galaxy S4 phone. The svg file either does not show, or just show the xml text.

    I was wondering whether you are aware of any solution to such problem.

    If this requires your time, I will be glad to discuss this further and compensate you for your time.

    Thanks,

    Daniel Abramovich

  5. Aaron says:

    wow. that makes life a lot easier. was so frustrating

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>