22

I have a web app that uses external background images loaded in external CSS. Right now, it is possible to use the app before the images have fully rendered, creating weird visual effects.

How can I halt script execution until the images are fully loaded?

It can use normal JavaScript or jQuery. Because the images are loaded in external CSS the normal triggers I have read about don't work.

Code Maverick
  • 20,171
  • 12
  • 62
  • 114
user3306770
  • 223
  • 1
  • 2
  • 4
  • 12
    I don't think this question is a duplicate. it specifically refers to background images, not image tags. – wusher Mar 12 '15 at 21:14
  • 5
    Absolutely not a duplicate question as @wusher states. OP is asking about background images. – Perry May 16 '16 at 19:20
  • 2
    I'm not sure if this has been clear for all of the 2½ years since this question was marked as a dupe, but it's crystal clear now, and honestly makes the moderators look bad. – Michael Scheper Dec 12 '16 at 07:41
  • This is not a duplicate. The answer links to jQuery and Images which is not helpful – Andy Jan 26 '21 at 08:06

4 Answers4

41

If you have an element with a background image, like this

<div id="test" style="background-image: url(link/to/image.png)"><div>

You can wait for the background to load by getting the image URL and using it for an image object in javascript with an onload handler

var src = $('#test').css('background-image');
var url = src.match(/\((.*?)\)/)[1].replace(/('|")/g,'');

var img = new Image();
img.onload = function() {
    alert('image loaded');
}
img.src = url;
if (img.complete) img.onload();
adeneo
  • 312,895
  • 29
  • 395
  • 388
  • 3
    Great! It's just not clear to me what the regex is doing? – MatheusJardimB Mar 24 '16 at 16:57
  • 2
    @MatheusJardimB - Background images in CSS are always added with `url(...)`, the regex get's the content inside `url(...)`, or in other words the source of the image, and the replace removes any quotes, as some browsers also add quotes when returning, i.e. `url("...")` – adeneo Mar 24 '16 at 18:21
  • 1
    Could you explain the last line, please? – Michael Scheper Dec 12 '16 at 07:47
  • 3
    @MichaelScheper - it's a common workaround to IE not firing the onload event on cached images. It's probably not needed anymore as newer versions of IE don't have this problem, but I always add it just to make sure anyway. – adeneo Dec 12 '16 at 17:59
2

There are no DOM events associated with CSS backgrounds. You'd have to count the images, assign onload events and add them as new Image() via JS, increment a counter as they load.

Diodeus - James MacFarlane
  • 112,730
  • 33
  • 157
  • 176
  • 1
    Contrary to what I had read about "no DOM events associated with CSS backgrounds", indeed my tests reveal that in modern browsers: $(window).load(function() { // all images loaded }); does the trick. It only fires after loading the external images in external CSS. I put a few 20+ meg image backgrounds in place to verify. If this hadn't worked, Plan B was using data URIs, but I am glad it didn't come to that. Thanks for the replies! – user3306770 Apr 01 '14 at 20:24
0

Check out this answer to a similar question:

I wrote a plugin that can fire callbacks when images have loaded in elements, or fire once per image loaded.

It is similar to $(window).load(function() { .. }), except it lets you define any selector to check. If you only want to know when all images in #content (for example) have loaded, this is the plugin for you.

It also supports loading of images referenced in the CSS, such as background-image, list-style-image, etc.

waitForImages jQuery plugin

Example Usage

 $('selector').waitForImages(function() {
     alert('All images are loaded.');
 });

Example on jsFiddle.

More documentation is available on the GitHub page.

Community
  • 1
  • 1
Code Maverick
  • 20,171
  • 12
  • 62
  • 114
-3

Contrary to what I had read about "no DOM events associated with CSS backgrounds", indeed my tests reveal that in modern browsers:

$(window).load(function() {
// all images loaded
});

does the trick. It only fires after loading the external images in external CSS.

I put a few 20+ meg image backgrounds in place to verify.

If this hadn't worked, Plan B was using data URIs, but I am glad it didn't come to that.

Thanks for the replies!

user3306770
  • 223
  • 1
  • 2
  • 4
  • 1
    This only works on the first page load. Not if you add/load new images into the DOM. I think the author looking for something like like this. – Sascha Aug 16 '16 at 06:32