19

Is it possible to listen for an <image> load event in SVG? If yes, how to do this?

JJJ
  • 32,902
  • 20
  • 89
  • 102
Rustam
  • 1,875
  • 2
  • 16
  • 33

2 Answers2

17

Yes it's possible.

In markup:

<image xlink:href="example.png" width="10" height="10" 
       onload="alert('loaded')"/>

See jsfiddle.

In script:

<script>
  var img = document.createElementNS("http://www.w3.org/2000/svg", "image");
  img.addEventListener('load', function() { alert('loaded'); });
  // or alternatively:
  // img.onload = function() { alert('loaded'); }
  img.width.baseVal.value = 100;
  img.height.baseVal.value = 100;
  img.href.baseVal = "example.png";
</script>

See jsfiddle.

Erik Dahlström
  • 59,452
  • 12
  • 120
  • 139
  • I'm unable to get this working, neither with markup nor script; are you able to provide an example? – Richard May 09 '13 at 09:15
  • http://www.w3.org/TR/SVG/interact.html#SVGEvents, have you tried the referenced externalResourcesRequired attribute, as mentioned the link? – neo Sep 18 '13 at 08:58
  • @neo: the externalResourcesRequired attribute is not necessary here. – Erik Dahlström Sep 18 '13 at 10:13
  • 2
    It appears that firefox doesn't fire load events for elements at all. All other browsers do however, see this testcase http://xn--dahlstrm-t4a.net/svg/events/load-events/image-root.svg. – Erik Dahlström Mar 13 '14 at 16:05
  • Correct, there's an [open Firefox bug](https://bugzilla.mozilla.org/show_bug.cgi?id=620002) for the lack of the `load` event on ``. I would suggest loading the image like `img = new Image(); img.onload = …; img.src = 'example.png'` instead of using an svg `image` tag like in Erik's example. – fregante Jun 08 '14 at 01:37
  • the onload event is not fired in chrome here – daslicht Apr 01 '18 at 10:24
  • @daslicht I checked the first example in Chrome Canary just now, and it seems to fire the load event - see http://jsfiddle.net/749WG/49/. If the image url is broken (server offline or similar) then no load will be fired, but you can also listen for the error event. – Erik Dahlström Apr 03 '18 at 07:36
  • @ErikDahlström yeah inline in html it is firing, but not if attached via js. As far as I know know iot is by design sicne Chome use strict. I havent managed tho, to get the content of a svg which is loaded into an image tag yet. – daslicht Apr 03 '18 at 11:14
  • @daslicht I just updated the js fiddle example, http://jsfiddle.net/ZXdxc/81/, and from what I can tell Chrome does fire load events. Perhaps post a new question with your non-working example? – Erik Dahlström Apr 04 '18 at 09:52
  • @ErikDahlström yeah that works in chome but not safari :) – daslicht Apr 04 '18 at 13:15
8

I found that this would not work for SVG object created using D3, but the answer here worked great:

How can I display a placeholder image in my SVG until the real image is loaded?

For example this worked:

var img = innerG.append("image")
    .attr('onload', function() {
        console.log('loaded');
    })
    .attr("xlink:href", src)
    .attr("width", size)
    .attr("height", size);

But this did not work:

var img = innerG.append("image")
    .attr("xlink:href", src)
    .attr("width", size)
    .attr("height", size);

img.addEventListener('load', function() { console.log('loaded'); });
Community
  • 1
  • 1
zayquan
  • 7,544
  • 2
  • 30
  • 39
  • 1
    But the attribute name is as HTML: `onload`. But the event name is different: `SVGLoad` not `load`. See http://www.w3.org/TR/SVG/interact.html#LoadEvent – mems Apr 01 '15 at 09:34
  • But in the second example, the load event is set up after the xlink:href attribute is set, so if the image loading is quick enough the event may not get triggered – mgraham Dec 18 '18 at 12:15
  • You generally need to set an event listener first, before setting data that triggers said event listener, to avoid race conditions where the data is done before the event listener can even be set. In the 2nd example, it will not work unless you put the `.attr("xlink:href", src)` second, after the `img.addEventListener('load', function() { console.log('loaded'); });` - notice how in the example that worked for you, the onload attr is set first, before setting src. – OG Sean Jan 14 '19 at 20:52