15

I want to run some code when an image is loaded. Also, I'd like to do it unobtrusively (not inline). More specifically, I want to use jQuery's live() function so it will happen for any dynamically loaded images.

I've tried:

<img class="content_image" alt="" src="..." />
<script>
    $('.content_image').live('load', function() {
      alert('loaded!');
    });
</script>

In addition to load, I've tried onload, and onLoad. When I replace with 'click' all works as expected so I know it's not some interfering bug.

I haven't been able to find a list of available event types for the live() function, so for all I know, it may not be possible.

Hakan Fıstık
  • 16,800
  • 14
  • 110
  • 131
tybro0103
  • 48,327
  • 33
  • 144
  • 170

3 Answers3

18

(It would be load, not onload or onLoad.)

load doesn't bubble (according to the img entry in the HTML5 spec, it's a "simple event", which don't bubble), so you can't use it with live or delegate, which rely on the event bubbling from an element to its ancestor element(s).

You'll have to hook it on the individual img elements (and do so before you set their src, since otherwise you can miss it; and always remember to watch for error as well). (Yes, you really can miss it: The browser is not single-threaded, just the JavaScript main thread. If you set src and the image is in cache or becomes available soon enough, the browser can fire the event. The way events are fired is that the browser looks to see what handlers are registered as of when the event is fired, and queues those to be called when the JavaScript main thread yields back to the browser. If there are no handlers registered, they aren't queued, and you never get the callback.)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Events are dispatched asynchronously so you are safe to set `.src`, then the listener. – J. K. Aug 13 '13 at 00:08
  • @IanKuca: No, you aren't, for exactly the reason you mention: Asynchronicity. The *browser* is not single-threaded, just the JavaScript main thread. If you set `src` and the image is in cache or becomes available soon enough, the browser can fire the event. It does that by looking to see what handlers are registered as of when the event is fired, and queuing those to be called. If there are no handlers registered, they aren't queued for callback, and you miss the event. I've seen it happen and helped at least a couple of people here on SO debug why they weren't getting the event. – T.J. Crowder Aug 13 '13 at 07:41
  • Excuse my ignorance: Does it means that I can't do: $("#my_document").on("load","img.my_image",function(){ change_size() }); ` ??? – Albert Català Jan 27 '16 at 16:05
  • 1
    @AlbertCatalà: That's correct, `load` doesn't bubble, so you can't use it with delegation. [jQuery's docs for `on`](http://api.jquery.com/on/) also mention that, and (unlike `focus`) it doesn't say jQuery updates that behavior for you. – T.J. Crowder Jan 27 '16 at 16:18
2

it's a little bit dirty, but it works :

<script type="text/javascript">
    var loop = setInterval(function() {

           // the img to watch
           var $img = $("img.hi");

           if( !!$img.length && $img[0].complete ) {
               // clear the timer
               clearInterval(loop);

               alert("loaded !");

           }

    }, 30);        
</script>

<img class="hi" src="http://www.google.fr/images/nav_logo72.png" />
Pirhoo
  • 680
  • 8
  • 21
  • 1
    It's *very* dirty. :-) Inventive, though. But if you're going to do that, you want to at least avoid looking through the DOM for the element again every ~30ms, by storing the reference somewhere (not globally of course, probably use a scoping function for it and for the `loop` handle). But there's no reason to do this, if he is going to do it for every element, `load` (+ `error`) is the better way, esp. as the above will loop forever if the image *doesn't* load. – T.J. Crowder Jul 05 '11 at 21:38
  • "dirty" and "inventive" are good adjectives here :) +1 for the inventive part – tybro0103 Jul 06 '11 at 01:31
  • You are absolutely right T.J. Crowder. The background idea is just to monitor the "complete" states, it could be a good trail... – Pirhoo Jul 06 '11 at 09:38
0

Finaly I stumbled upon this jQuery plugin : https://github.com/desandro/imagesloaded

Pirhoo
  • 680
  • 8
  • 21