2

I would like to dynamically insert an image in a webpage using javascript. The easiest way of course is just to update the 'src' tag of an element. However, the image is actually a dynamically generated PNG, and it takes about 15sec to generate it every time. If I just update the 'img' tag, I am afraid impatient users will think the url is dead and leave the page before it displays, therefore I would like to display a loader.

In order to be able to display a loader I have to download the image through Ajax, and then insert in in the document. Is this possible? I tried to first do an Ajax request, and then when it succeeds update the img src tag hoping that browsers would be smart enough not to re-downoad the image, but apparently this is not the case.

Is there any workaround to have control over the http request of the img without introducing new server code?

Jeroen
  • 28,942
  • 33
  • 116
  • 190
  • I posted an answer using the `load()` technique, but the jQuery manual has lots of bad things to say about the `load()` event on images: http://api.jquery.com/load-event – Pekka May 29 '11 at 06:58

4 Answers4

4

When the page is loaded you could show some dummy image which will represent the loading progress:

<img src="loader.gif" id="myimg" />

and then replace it with the actual dynamic image:

$(function() {
    $('#myimg').load(function() {
        $(this).unbind('load');
        this.src = '/script/dynamicimage';
    });
});
Darin Dimitrov
  • 960,118
  • 257
  • 3,196
  • 2,876
  • This sounds like the best approach because it doesn't depend on the `load` event being reliable, which it [isn't](http://api.jquery.com/load-event). I don't understand why you wrap it into the "please wait" image's load event though? – Pekka May 29 '11 at 07:00
  • 1
    @Pekka, I am wrapping it in "please wait" image's load event because I am doing this in document.ready when only the DOM is guaranteed to be loaded, not images and this will ensure that the user sees the progress image before modifying its `src` property. If you do it before he might never see the actual loading image. – Darin Dimitrov May 29 '11 at 07:07
  • but seeing the loading image has no value in itself, does it? Using the `load` event carries the risk that it won't fire for one of the reasons listed in the [jQuery docs on `load()`](http://api.jquery.com/load-event) (like in Webkit, when the image is cached). The core of your solution doesn't *need* to depend on `load()`, which is why I think it is the only worthwhile one - *if* you weren't using `load()` – Pekka May 29 '11 at 07:17
1

You could show the loader, and then download the slow image in a hidden tag with an Ajax request, and then when it's loaded hide the loader and display the img.

EDIT: as pointed out by Pekka, load() is unreliable, so that's a no-go. This post deals with the same problem and provides 2 possible solutions:

  1. Use $(window).load to detect when ALL elements in the page (including images) have been loaded. This may or not be suitable, depending on your needs.
  2. There's a link to a snippet in github with a $().imagesLoaded function that is mostly a hack for working around this problem.
Community
  • 1
  • 1
axel_c
  • 5,991
  • 2
  • 26
  • 40
  • The load event is not perfectly reliable. See the caveats in http://api.jquery.com/load-event – Pekka May 29 '11 at 07:11
0

It's not very clear what you are trying to do, however...
1.First, attach a load event handler to your image tag, the one you're going to set its src to the newly created image. Make this img tag load the loader animation for example, or just use another tag for that one.
2.Then do an AJAX request to the server script that generates your dynamic image.
3.On the success callback of the AJAX call set the src of the previous mentioned img tag to the image the server has just created. Bare in mind that the fact that the image took time to generate on the server doesn't mean the browser won't take it's own time to load it.
That's why we have attached the load event handler to it before.

Also, hide the loader if you've used a separate DOM element for it.

This should also cover issues with browsers not firing the load event for cached images.

cbaltatescu
  • 267
  • 1
  • 3
  • 7
  • The load event is not perfectly reliable. See the caveats in http://api.jquery.com/load-event – Pekka May 29 '11 at 07:08
  • The load event will cause issues for images loaded from HTML but having experimented with this on a few browsers (FF, IE, Chrome) I can say that attaching a load event prior to changing the src of the image shouldn't cause issues with cached images. However the rest of the caveats, regarding bubbling and setting the same src as before will still apply. – cbaltatescu May 29 '11 at 08:00
0
  1. Send an ajax request to download the image and show the loading animation.
  2. On server side, when request is received, create the image and save it in a temporary place.
  3. Send back ajax response to browser the path of image.
  4. Change the src attribute of image one got through ajax.

I hope it will work.

Imran Naqvi
  • 2,102
  • 4
  • 25
  • 51