2

It's age old question of how to preload css background images, but with a little twist: the background images are being set via jQuery as they are from Vimeo. Each background image is a video image from vimeo, so I'm setting the background using the vimeo thumbnail url when the site loads. Can I somehow preload these images? I have an overlay in place that I want to disappear when the content is loaded, but despite my efforts, the background images are still visibly loading when the overlay disappears!

Here is some (not so eloquent) code that I've tried:

var count = $('.video_stub').length; $('.video_stub').each(function(index) { var bgUrl = $(this).data('thumb'); $('<img/>')[0].src = bgUrl; if(index == (count - 1)) { $('.video_stub').each(function(i) { var bgUrl = $(this).data('thumb'); // Set the video thumb's background using the vimeo thumb image $(this).css('background-image', 'url(' + bgUrl + ')'); if(index == (count - 1)) { $('#temp_overlay').fadeOut('slow'); } }); } }); 

Any ideas? Thanks so much in advance.

EDIT:

I tried this code, but with no success. I'm wondering if it's a scope issue? Maybe I'm not able to access the index variable from within the load callback:

// Set video thumb click handler var count = $('.video_stub').length; // Set video thumb click handler // Iterate through each video stub $('.video_stub').each(function(index) { var bgUrl = $(this).data('thumb'); $('<img/>').attr('src', bgUrl).load(function() { $('.video_stub:eq(' + index + ')').css('background-image', 'url(' + bgUrl + ')'); }); if(index == (count - 1)) { $('#temp_overlay').fadeOut('slow'); } }); 

I tried:

$('<img/>').attr('src', bgUrl).load(function() { $(this).css('background-image', 'url(' + bgUrl + ')'); }); 

to no avail.

1
  • Thanks for the edit j08691, didn't mean to leave so many arbitrary spaces :P Commented Sep 25, 2012 at 21:18

4 Answers 4

2

The following should work:

var video_stubs = $('.video_stub'); var loaded = []; video_stubs .each(function(){ /// store stub as a var so we can correctly access it in the callback var stub = $(this); /// get the URL as usual var bgURL = stub.data('thumb'); /// create a temporary image that tells the browser to load a specific /// image in the background $('<img />') /// define our load event before we set the src value otherwise the /// load could happen from cache before we've even defined a listener .load(function(){ /// set the background image $(this) no longer points to stub, /// it actually points to the temporary image.. so instead /// use the stub var we've created outside of this scope stub.css('background-image', 'url(' + bgURL + ')'); /// store a list of what we've loaded - mainly for the loaded.length /// count - but storing this information could be useful elsewhere loaded.push( bgURL ); /// test that we've all loaded (remember this can occur in any order) /// so keeping an incrementing count is better than assuming the last /// image we try and load will be the last image to load completely. if ( loaded.length == video_stubs.length ) { /// finalise only after all is loaded $('#temp_overlay').fadeOut('slow'); } }) /// set the src value, once loaded the callback above will run .attr('src', bgURL) ; }) ; 

The main problem with what you've attempted already is that you are trying to reference $(this) inside a callback function. You have to make sure you know where this is referencing. With jQuery this will always be the targetted elements within the collection that triggers the callback. So in the examples I've seen above you are actually trying to access the temporary image, rather than the stub.

Sign up to request clarification or add additional context in comments.

9 Comments

I like this solution, and it makes sense, but somehow the background images aren't ending up loaded after the overlay fades out... I have no idea why! This code seems like it should work perfectly.
@GionaF thanks :) Hendeca have you tried adding an alert/console.log in to make sure that bgURL is getting set with the right background path... and that the background paths are actually viewable as images (i.e. paste the path in a browser and make sure it loads) - other than that I'm not sure what to suggest (without seeing a live example of your site).
@Hendeca Also, how are you defining your 'thumb' data on the stub.. ?
@pebbl Oh gosh, I'll have to count this as another one of my epic brainfarts. I was foolishly placing the vimeo thumb url as a data attribute instead of just writing the style inline when generating the video stub elements. Now I can use a traditional preloader :P sorry guys, I'm an idiot!
Leave it for other people who'll find @pebbl reply useful ;) and open a new question for your updated situation
|
1

If you really need the images to be 100% visible after the overlay disappear, try to remove it when $(window) is loaded.

if(index == (count - 1)) { $(window).on('load',function(){ $('#temp_overlay').fadeOut('slow'); } } 

But be careful, because the users will have to wait for every content (internal and external) to be loaded before the overlay disappears. Maybe you can add a "skip loading" link.

6 Comments

I'm using $(document).ready but I don't see how this would help since the background images are loaded via Javascript. Seems it would still have the same effect since the $(window).load function would fire before the images are loaded.
Add the listener after you include the images...check my edit
Oh I see! Wow, you weren't kidding about that load time. Around a full minute. Seems impractically long. I feel if I could just target the css background images, it would make for a more sensible preloader.
Yep think so (maybe, but maybe the full minute is just caused by the Vimeo thumbs loading). But can't figure a way to add a listener to all of them... Let me think more hehe
Starting to consider caching the images server-side, since the videos won't change once uploaded. Maybe it's a more sensible solution? Would it actually decrease the load time significantly to load from the server instead of the Vimeo server?
|
0

You can check whether image has been loaded with this jQuery function:

$('img').load(function() { $('#temp_overlay').fadeOut('slow'); }); 

2 Comments

OP is talking about background images, so this won't work...Anyway, your starting point is better then mine, but it'll be hard to add a listener for every image he's adding dinamically :-)
True...Another workaround is using the following function which makes sure that once images are preloaded, certain action is taken: ditio.net/2010/02/14/jquery-preload-images-tutorial-and-example It works for the images which can be dynamically retrieved as soon as you define each image variable first
0

I was using queryLoader2 as my preloader, which parses through images and background images on the site. However, I was adding in some of the background images via javascript (instead of writing them into the css or into the style tag of each element) so the preloader couldn't actually load these images.

After I changed the code in a way that included the background image attribute in each element's "style" tag, I was able to load the images successfully!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.