Firstly, I have been researching this for a while, but I feel like this problem is a little beyond my abilities to solve on my own. Or at least, beyond my experience at this point, as I have never done this before.
I have a <div>
that contains an <img>
tag which I use JavaScript to change the source of to create a simple slideshow.
The Simple HTML:
<div id="slideShowWrapper">
<img id="slideShowImage" src="~/Images/City_Images/Okmulgee_Clock_2.jpg" alt="Okmulgee Clock" title="Slide Show Paused" />
</div>
The problem I am having is that when a user visits the site for the first time, the images take too long to load during their first pass through the slideshow, and it throws of the timing of the slideshow. Once the browser has the images cached, it works fine. If there were a way to load all of the pictures before the slideshow starts I believe it would fix the problem. During testing, this problem never arose because the images were already cached by my browser so no excessive loading time was needed.
Here is the JavaScript (jQuery) I use for the slide-show. The images originally come from a server-side database so I use AJAX to get the file name values I need (currently there are only 14 entries/pictures in the database, but this number could increase or decrease as site admins will be able to edit the pictures in the slideshow through a partial CMS). To explain some of the code, this slide-show has the functionality to pause on mouse-over and resume on mouse-out.
jQuery(function ($) {
//Slideshow functionality
var paths = new Array();
var timer = new Array();
var pathsString = "";
var i = 1;
var panel = $("img#slideShowImage");
var fTimer;
var tTimer;
var t2Timer;
var fadingOut = false;
var slideShowOn = false;
var showTimer;
$.ajax({
url: "/AJAX Pages/Compute_Slide_Show.cshtml",
async: false,
type: "GET",
success: function (response) {
paths = response.split("/*\\");
},
error: function (jqXHR, textStatus, error) {
paths[0] = "Okmulgee_Clock_2.jpg";
}
});
if (paths.length > 0) {
panel.attr("src", "/Images/SlideShowPics/" + paths[0])
if (paths.length > 1) {
swapImage();
}
}
else {
panel.attr("src", "/Images/City_Images/Okmulgee_Clock_2.jpg");
}
panel.mouseout(function () {
if (paths.length > 1) {
runSlideShow();
}
});
panel.mouseover(function () {
if (paths.length > 1) {
stopSlideShow();
}
});
function runSlideShow() { //Calls the swapImage function to begin or resume the slide show
if (slideShowOn == false) {
slideShowOn = true;
if (fadingOut == false) {
clearTimeouts();
}
showTimer = setTimeout(swapImage, 1552);
}
};
function stopSlideShow() { //Pauses the slide show
clearTimeout(showTimer);
if (fadingOut == true) {
fTimer = setTimeout(clearTimeouts, 1551);
}
else if (fadingOut == false) {
clearTimeout(tTimer);
clearTimeouts();
}
slideShowOn = false;
};
function swapImage() { //Fades out the slideshow image
tTimer = setTimeout(function () { fadingOut = true }, 4549);
timer[0] = setTimeout(function () { panel.css('opacity', '0.9') }, 4550);
timer[2] = setTimeout(function () { panel.css('opacity', '0.8') }, 4600);
timer[4] = setTimeout(function () { panel.css('opacity', '0.7') }, 4650);
timer[6] = setTimeout(function () { panel.css('opacity', '0.6') }, 4700);
timer[8] = setTimeout(function () { panel.css('opacity', '0.5') }, 4750);
timer[10] = setTimeout(function () { panel.css('opacity', '0.4') }, 4800);
timer[12] = setTimeout(function () { panel.css('opacity', '0.3') }, 4850);
timer[14] = setTimeout(function () { panel.css('opacity', '0.2') }, 4900);
timer[16] = setTimeout(function () { panel.css('opacity', '0.1') }, 4950);
timer[18] = setTimeout(function () { panel.css('opacity', '0') }, 5000);
timer[20] = setTimeout(swapImage2, 5050);
}
function swapImage2() { //Changes and fades in the slideshow image
panel.attr("src", "/Images/SlideShowPics/" + paths[i]);
if (i < paths.length - 1) {
i++;
}
else {
i = 0;
}
timer[21] = setTimeout(function () { panel.css('opacity', '0.1') }, 550);
timer[23] = setTimeout(function () { panel.css('opacity', '0.2') }, 600);
timer[25] = setTimeout(function () { panel.css('opacity', '0.3') }, 650);
timer[27] = setTimeout(function () { panel.css('opacity', '0.4') }, 700);
timer[29] = setTimeout(function () { panel.css('opacity', '0.5') }, 750);
timer[31] = setTimeout(function () { panel.css('opacity', '0.6') }, 800);
timer[33] = setTimeout(function () { panel.css('opacity', '0.7') }, 850);
timer[35] = setTimeout(function () { panel.css('opacity', '0.8') }, 900);
timer[37] = setTimeout(function () { panel.css('opacity', '0.9') }, 950);
timer[39] = setTimeout(function () { panel.css('opacity', '1') }, 1000);
t2Timer = setTimeout(function () { fadingOut = false }, 1050);
timer[41] = setTimeout(swapImage, 1050);
}
function clearTimeouts() { //Clears all slide show timers
for (key in timer) {
clearTimeout(timer[key]);
}
}
});
I tried reading up on this myself, but I am not getting answers that I feel I can adapt to my code. Either that or the solution is above my head.
SO sites I read up on:
Slideshow starts while images are loading but first image isn't displayed until all are downloaded
loading all images before slideshow
If you want to check out the problem yourself, you should be able to get there by visiting this link: http://test.cityofokmulgee.org:54543
Remember that this error is probably only going to naturally show up the first time you load up the page. After that your browser will have cached the images and the load time won't throw off the timing of the slide-show (unless you clear the images from the browser cache, something I have been unsuccessful in doing, myself). Also, I'm not sure if this issue will even show up in Chrome, but I know it does in IE.
Any help is much appreciated, as this is the major bug disallowing this site to go live, and I have never done anything like pre-loading images before, so I don't have any idea where to start.
Additional Info That Might Be Useful:
The contents of the server-side file, Compute_Slide_Show.cshtml (written in C#):
@{
Layout = "";
string fileNames = "";
if(IsAjax)
{
var db = Database.Open("Content");
bool firstRun = true;
foreach (var row in db.Query("SELECT FileOrder, FileName FROM SlideShow WHERE FileName IS NOT NULL AND FileName <> '' ORDER BY FileOrder ASC"))
{
if (firstRun == true)
{
firstRun = false;
fileNames += row.FileName;
}
else
{
fileNames += "/*\\";
fileNames += row.FileName;
}
}
}
else
{
Context.RedirectLocal("~/home.cshtml");
}
@:@fileNames
}