I'm working on a site that is very background-image intensive. Sinc开发者_StackOverflow中文版e some of the images are large, the aesthetic appeal of the page will inevitably suffer at the initial load, probably for several seconds.
So I'm trying to make a background-image preloader with jQuery and here's where I'm at:
$(document).ready(function(e){
$('*')
.each(function(){
if($(this).css('background-image') != 'none'){
//so, i can get the path, where do i go from here?
alert($(this).css('background-image').slice(5, -2));
}
});
});
I'm used an array of Image()
objects, to load the image using the path pulled from my iterator, but I'm lost on where to go from here.
How can I determine when all of the images in the array have 'loaded', so that I can call a function to fade out a preloader curtain or something?
You should be able to pull off something like this (untested!):
$(document).ready(function(e){
// get a collection of all elements with a BG image
var bgImages = $('*').filter(function(){
return $(this).css('background-image') != 'none');
// get a collection of new images, assigning the sources from the original collection
}).map(function() {
return $("<img />").attr("src", $(this).css('background-image').slice(5, -2));
});
var len = bgImages.length;
var loadCounter = 0;
// use an onload counter to keep track of which ones have loaded
bgImages.load(function() {
loadCounter++;
if(loadCounter == len) {
// we have all loaded
// fade out curtain
}
}).each(function() {
// if we have been pulled up from cache, manually trigger onload
if (this.complete) $(this).trigger("load");
});
});
Here are a few resources to look at:
- Image Preloader
- Preloader with Callback
If you use a DOM element
instead of Image
you can watch the image onload
callback
var path = $(this).css('background-image').slice(5, -2);
var img = document.createElement('img');
img.src = path;
$(img).load(function(){ /* incrament counter for loaded images */})
// Get all backgrounds
var bgImages = $('*').filter(function()
{
return ($(this).css('background-image') != 'none');
})
// Create IMG objects for it
.map(function()
{
// Works in Chrome!!! Chrome not uses brackets near url()
return $('<img />').attr('src', $(this).css('background-image').replace(/\url|\(|\"|\"|\'|\)/g, ''));
});
var len = bgImages.length;
var loadCounter = 0;
$(bgImages).each(function()
{
$(this).load(function()
{
loadCounter++;
console.log(loadCounter); // Look at console
if(loadCounter == len) { // ALL LOADED!!! }
});
})
// Cached trigger
.each(function()
{
if (this.complete) $(this).trigger('load');
});
Thanks to karim79 and Josiah Ruddell. I've solved it for the time being, using a bit of a hybrid from suggestions and trial and error:
var preloaderTotal = 0;
var preloaderLoaded = 0;
var preloaderCurrent = null;
$('#preloaderCurtain')
.bind('preloaderStart', function(){
$(this)
.show();
$('*')
.filter(function(e){
if($(this).css('background-image') != 'none'){
preloaderTotal++;
return true;
}
})
.each(function(index){
preloaderCurrent = new Image();
preloaderCurrent.src = $(this).css('background-image').slice(5, -2);
preloaderCurrent.onload = function(e){
preloaderLoaded++;
if(preloaderLoaded == preloaderTotal - 1){
$('#preloaderCurtain')
.trigger('preloaderComplete')
}
$('#preloaderCurtain')
.trigger('preloaderProgress')
};
});
})
.bind('preloaderComplete', function(){
$(this)
.fadeOut(500)
startAnimation();
})
.bind('preloaderProgress', function(e){
$('#preloaderProgress')
.css('opacity', 0.25 + (preloaderLoaded / preloaderTotal))
.text(Math.floor((preloaderLoaded / preloaderTotal) * 100) + '%');
})
.trigger('preloaderStart');
精彩评论