So, I think there are many ways to approach the subject of pre-loading images, or loading images on demand… but I wanted to share with you how I normally create a dynamic JavaScript based application. I call this “my logic” or “my methodology” as it’s something I thought up without looking at another developers code. I also use this same methodology in my post on the Facebook-style infinite wall posting.
I am not sure if any other people use this method, but my theory/logic uses placeholders, with a script that is called on a specific event (scrolling down/rotate/etc) to detect and load content/graphics to replace the empty placeholder. These same principals are used in my “facebook-like” infinitely scrolling wall post, just with a different application. The reason I do this, is it’s an easy way to detect how much content is not loaded, and load on demand.
In video above, I explain try to briefly explain how my placeholders work, and I’ll explain in detail below why I do things this way.
LET’S GET STARTED:
The first thing you will need is a data source, in this instance I have a JSON object holding my images and text along with as other supporting content. We’ll use this to data object build out my structure, as well as load my initial data to the page. I’ve shortened this object down to only include two items for simplicity.
"features" : [
{
"title" : "Hollidaysburg",
"droid" : "_screenshots/droid-hollidaysburg.jpg",
"iphone" : "_screenshots/iphone-hollidaysburg.jpg",
"web" : "_screenshots/web-hollidaysburg.jpg",
"color" : "#E5ECF2",
"quote" : "Extending the Schoolwires experience to the mobile environment is very exciting. The Schoolwires mobile application looks great and is easy to use. We look forward to offering this to our district and community.",
"quotee" : "Robin Smith",
"jobtitle" : "Director of Technology"
},
{
"title" : "Spring Grove",
"droid" : "_screenshots/droid-springgrove.jpg",
"iphone" : "_screenshots/iphone-springgrove.jpg",
"web" : "_screenshots/web-springgrove.jpg",
"color" : "#FFFFFF",
"quote" : "Schoolwires stands out as providing the most robust Content Management platform. Their new Centricity2 mobile product augments this significance to our community stakeholders.",
"quotee" : "Name",
"jobtitle" : "Title"
}
]
};
You can easily get the size of your JSON object by using the .length property. If you have never worked with JSON before, it’s worth researching and is very powerful, especially when you are building JavaScript applications. JSON is JavaScript so they work amazing when combined.
The third thing you will need is your initial function to push the data to the page. You can push no data, one item, two items, etc… It’s really up to you and really should be dependent on the applications needs. In my instance I am loading two images on ready, one for the active showing image, then the image to the right we’ll be sliding to within 7 seconds.
buildData();
});
function buildData(){
for(j=0;j<numItems+1;j++){
if(j==numItems) {
$("#ss-slider").append("<img src='" + folderPath + mJSON.features[0].web + "' />");
$("#droid-slider").append("<img src='" + folderPath + mJSON.features[0].droid + "' />");
$("#iphone-slider").append("<img src='" + folderPath + mJSON.features[0].iphone + "' />");
} else {
//PUSH QUOTES
$("#quotes-container").append("<div class='quote'><h2>" + mJSON.features[j].quote + "</h2><h5>" + mJSON.features[j].quotee + "</h5><h6>" + mJSON.features[j].jobtitle + "</h6></div>");
//HARD INSERT FIRST TWO IMAGES
if(j<2){
$("#ss-slider").append("<img src='" + folderPath + mJSON.features[j].web + "' />");
$("#droid-slider").append("<img src='" + folderPath + mJSON.features[j].droid + "' />");
$("#iphone-slider").append("<img src='" + folderPath + mJSON.features[j].iphone + "' />");
} else {
//PUSH EMPTY IMAGE TAGS FOR AJAX
$("#ss-slider").append("<span class='not-loaded' />");
$("#droid-slider").append("<span class='not-loaded' />");
$("#iphone-slider").append("<span class='not-loaded' />");
}
}
}
$(".quote:first").show();
rotate();
}
You will need some sort of function to check for a change, or an event. In this case, we are sliding the images every 7 seconds. Here is my setInterval function:
window.setInterval(function(){
slideNext();
}, 7000);
}
The next function is the actual fun part, the animation. This is a simple jQuery based .animate() which will slide to the left the pixel width of the image area. As the animation is happening, i also call the preloader function to get the next image loaded into the page as well.
if(active == numItems) {
$("#ss-slider, #droid-slider, #iphone-slider").css("left","0px");
active = 0;
}
$("#ss-slider").animate({
"left" : "-=658px"
}, 1000);
$("#droid-slider").animate({
"left" : "-=125px"
}, 1000);
$("#iphone-slider").animate({
"left" : "-=130px"
}, 1000);
$(".quote").eq(active).fadeOut(600, function(){
if($(this).next().length == 0) {
$(".quote:first").fadeIn(1000);
} else {
$(this).next().fadeIn(1000);
}
});
//CALL PRELOADER
if($("#ss-slider .not-loaded").length){
preloadImages();
}
active++;
}
The last function is called as the animation is happening (see above “CALL PRELOADER” comment). This function first looks into the container of slides, and gets the index() of the first “not-loaded” classed item. This is great, because it tells us which index # to pull from our data source. So we do a simple .load() function to pull in the image, and then once loaded, we place the item before the first not-loaded item, then remove the not-loaded item. Hopefully that makes sense! In this instance I have 3 images to load, one main screenshot image of the website, then two smaller images for the mobile screenshots. I load the main image, then call both the smaller images at the same time on complete of the main image load.
var myLoadNum = $("#ss-slider .not-loaded:first").index();
$("<img src='" + folderPath + mJSON.features[myLoadNum].web + "'/>").load(function(){
$(this).insertBefore($("#ss-slider .not-loaded:first"));
$("#ss-slider .not-loaded:first").remove();
//LOAD OTHER TWO IMAGES
$("<img src='" + folderPath + mJSON.features[myLoadNum].droid + "'/>").load(function(){
$(this).insertBefore($("#droid-slider .not-loaded:first"));
$("#droid-slider .not-loaded:first").remove();
});
$("<img src='" + folderPath + mJSON.features[myLoadNum].iphone + "'/>").load(function(){
$(this).insertBefore($("#iphone-slider .not-loaded:first"));
$("#iphone-slider .not-loaded:first").remove();
});
});
}
Hope it all makes sense!
Joel