0

Beginner question here. I am building a photo viewer using JavaScript and jQuery.

When you click on the arrow to see the next picture, I want the current picture to fade out, then the next picture to fade in. The problem I was getting is that if the picture took a little longer to be loaded, I was getting the old picture to still be there when the fade in started so in essence what I need is to make sure that the fade in doesn't kick in until the new picture has been loaded.

So these three statements must be run each one only executing if the previous has been executed:

$('#image').fadeOut(500);
getImage();
$('#image').fadeIn(500);

And here is my function to get the new image:

getImage = function() {
    document.getElementById("image").src = "Images/Image" + counter + ".jpg";
}

Where counter is a variable I declared earlier that gets updated when you click on the "next" button etc...

So, not knowing that much about programming, I am looking for a way to make sure that

$('#image').fadeIn(500);

Doesn't run unless the new image has been fetched or what happens is that the old image starts fading in then we get the new one.

I tried with a call back, like so:

$('#image').fadeOut(500, function() {
        getImage();
});

$('#image').fadeIn(500);

But that doesn't work as you would need a fall back within the fallback and I don't know how to do this.

Another thing I have tried is to do something like this:

var hasloaded = $('#image').fadeOut(500, function() {
    getImage();
});

if (hasloaded)
{$('#image').fadeIn(500);}

And that doesn't work either, although I thought I was being really clever when I wrote it.

Any help appreciated.

Thanks.

Paul
  • 1,277
  • 5
  • 28
  • 56
  • 1
    Your `getImage()` function must provide some mechanism to run code when the image has been fetched. Make it accept a callback that it invokes at the proper moment or make it return a promise that gets resolved at the proper moment – Lennholm Jul 31 '17 at 09:32

1 Answers1

2

You can create a JavaScript Image object and in the load event set the src to target element

$('#image').fadeOut(500, function () {
    getImage(function () {
        $('#image').fadeIn(500);
    });
});

getImage = function (cb) {
    var img = new Image();
    img.onload = function () {
        document.getElementById("image").src = img.src;
        cb();
    };
    img.src = "Images/Image" + counter + ".jpg";
}

Using promise()

$('#image').fadeOut(500, function () {
    getImage().then(() => {
        $('#image').fadeIn(500);
    });
});

getImage = function () {
    return new Promise((resolve, reject) => {
        var img = new Image();
        img.src = "Images/Image" + counter + ".jpg";
        img.onload = function () {
            document.getElementById("image").src = img.src;
            resolve("Success!");
        };
    });
}
Satpal
  • 132,252
  • 13
  • 159
  • 168
  • Hi, thanks for this, it has worked. I would like to understand how his cb() works. Is there any article you could point me to? thanks – Paul Jul 31 '17 at 11:01
  • @Paul, `cb()` is a simple callback function. I would suggest [How to return the response from an AJAX call](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) – Satpal Jul 31 '17 at 14:21