Using AJAX / jQuery to refresh an image

This is probably a simple question but I am stumped and just don’t know where to start.

I have a PHP script (image_feed.php) that returns a URL to an image. Every time this URl is called it returns the latest image available (the image changes every couple of seconds).

What I want to happen is that when the page loads, there is an AJAX call to image_feed.php, which returns the latest url. This URl is then inserted into the HTMl replacing the appropriate image src.

After 5 seconds, I want the process to repeat, and for the image to update. However, I don’t want the image to be swapped until it has finished loading, and I want to avoid a white space appearing before the new image loads.

At the moment I have the following jQuery, which simply loads the return value of image_feed.php directly into a div called #image1. image_feed.php is correctly formatted to provide a html image tag.

    $(document).ready(function(){
    var $container = $("#image1");
    $container.load('image_feed.php?CAMERA_URI=<?=$camera_uri;?>')
    var refreshId = setInterval(function()
    {
        $container.load('image_feed.php?CAMERA_URI=<?=$camera_uri;?>');
    }, 5000);

}); 

This works, but there is a problem. I get a white space the size of the image in IE and Firefox every time the image refreshes, because the image takes a while to download.

I know what I need to is for image_feed.php to return the plain URL to the image. I then use some jQuery to request this URL, pre-load it and then swap it with the existing image.

However, I’m still struggling to get anywhere. Could someone be so kind as to give me some pointers / help?

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

$(document).ready(function() {
    var $img = $('#image1');
    setInterval(function() {
        $.get('image_feed.php?CAMERA_URI=<?=$camera_uri;?>', function(data) {
            var $loader = $(document.createElement('img'));
            $loader.one('load', function() {
                $img.attr('src', $loader.attr('src'));
            });
            $loader.attr('src', data);
            if($loader.complete) {
                $loader.trigger('load');
            }
        });
    }, 5000);
});

Untested. Code above should load the new image in the background and then set the src attribute of the old image on load.

The event handler for load will be executed only once. The .complete check is necessary for browsers that may have cached the image to be loaded. In such cases, these browsers may or may not trigger the load event.

Solution 2

You can. When you want to reload something, you can just append a search query, so that it refreshes the source.

For Eg., when there is a frequently changing image (say captcha) and you wanna load it again, without refreshing the browser, you can do this way:

Initial Code:

<img src="captcha.png" alt="captcha" />

Refreshed Code:

<img src="captcha.png?1" alt="captcha" />

The script used here would be just:

var d = new Date();
$('img').attr('src', $('img').attr('src') + '?_=' + d.getMilliseconds());

Hope this helps! 🙂

Solution 3

Consider, if you have to fetch the URL again from the server, for a new image URL, you can do this way:

$.ajax({
  url: 'getnewimageurl.php',
  success: function(data) {
    $('img').attr('src', data);
  }
});

The server should return only a new image name in it. For eg., the PHP code should be this way:

<?php
    $images = array("jifhdfg", "jklduou", "yuerkgh", "uirthjk", "xcjhrii");
    die($images[date('u') % count($images)] . ".png"); // Get the random milliseconds mod by length of images.
?>

Solution 4

I suggest you use jQuery ‘onImagesLoad’ Plugin
This provides you with a callback when an image has finished loading.

When you receive new image URL from server, you create a new <img object with src="new_url_from_server" and attach 'onImagesLoad' callback to it. When your callback is called, your image has finished downloading.

Now you can just replace the ‘src’ attribute of old img object with new_url_from_server.
Since new image is already avaiable in cache, it will not be downloaded again and will be immediately displayed!

Aletrnatively, you can hide the old image and add this new image to DOM (not required if above works correctly)

Some bare bones sample could be like this:

<!DOCTYPE html> 
<html> 
<body> 
<img id='bla' src="10.jpg" />

<script type="text/javascript" src="jquery.min.js"></script> 
<script type="text/javascript" src="jquery.onImagesLoad.js"></script> 
<script type="text/javascript"> 
    $(function(){ 
        var img = $('<div><img src="https://myserverbla/images/verybig.jpg"></img></div>');
        img.onImagesLoad({ 
                all : allImgsLoaded 
            });

        function allImgsLoaded($selector){ 
            var allLoaded = ""; //build a string of all items within the selector 
            $selector.each(function(){ 
                $('#bla').attr('src','http://myserverbla/images/verybig.jpg');
            }) 
        } 
    }); 
</script> 

</body> 
</html>

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply