How can I check if a background image is loaded?

JavascriptJquery

Javascript Problem Overview


I want to set a background image on the body tag, then run some code - like this:

$('body').css('background-image','http://picture.de/image.png').load(function() {
    alert('Background image done loading');
    // This doesn't work
});
    

How can I make sure the background image is fully loaded?

Javascript Solutions


Solution 1 - Javascript

try this:

$('<img/>').attr('src', 'http://picture.de/image.png').on('load', function() {
   $(this).remove(); // prevent memory leaks as @benweet suggested
   $('body').css('background-image', 'url(http://picture.de/image.png)');
});

this will create a new image in memory and use load event to detect when the src is loaded.

EDIT: in Vanilla JavaScript it can look like this:

var src = 'http://picture.de/image.png';
var image = new Image();
image.addEventListener('load', function() {
   body.style.backgroundImage = 'url(' + src + ')';
});
image.src = src;

it can be abstracted into handy function that return a promise:

function load(src) {
    return new Promise((resolve, reject) => {
        const image = new Image();
        image.addEventListener('load', resolve);
        image.addEventListener('error', reject);
        image.src = src;
    });
}

const image = 'http://placekitten.com/200/300';
load(image).then(() => {
   body.style.backgroundImage = `url(${image})`;
});

Solution 2 - Javascript

I have a jQuery plugin called waitForImages that can detect when background images have downloaded.

$('body')
  .css('background-image','url(http://picture.de/image.png)')
  .waitForImages(function() {
    alert('Background image done loading');
    // This *does* work
  }, $.noop, true);

Solution 3 - Javascript

There are no JS callbacks for CSS assets.

Solution 4 - Javascript

Something like this:

var $div = $('div'),
  bg = $div.css('background-image');
  if (bg) {
    var src = bg.replace(/(^url\()|(\)$|[\"\'])/g, ''),
      $img = $('<img>').attr('src', src).on('load', function() {
        // do something, maybe:
        $div.fadeIn();
      });
  }
});

Solution 5 - Javascript

pure JS solution that will add preloader, set the background-image and then set it up for garbage collection along with it's event listener:

Short version:

const imageUrl = "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png";
let bgElement = document.querySelector("body");
let preloaderImg = document.createElement("img");
preloaderImg.src = imageUrl;

preloaderImg.addEventListener('load', (event) => {
    bgElement.style.backgroundImage = `url(${imageUrl})`;
    preloaderImg = null;
});

A bit longer with nice opacity transition:

const imageUrl = "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png";
let bgElement = document.querySelector(".bg-lazy");
bgElement.classList.add("bg-loading");
let preloaderImg = document.createElement("img");
preloaderImg.src = imageUrl;

preloaderImg.addEventListener('load', (event) => {
  bgElement.classList.remove("bg-loading");
  bgElement.style.backgroundImage = `url(${imageUrl})`;
  preloaderImg = null;
});

.bg-lazy {
  height: 100vh;
  width: 100vw;
  transition: opacity 1s ease-out;
}

.bg-loading {
  opacity: 0;
}

<div class="bg-lazy"></div>

Solution 6 - Javascript

Here is a small plugin I made to allow you to do exactly this, it also works on multiple background images and multiple elements:

Read the article:

http://catmull.uk/code-lab/background-image-loaded/

or go straight to the plugin code:

http://catmull.uk/downloads/bg-loaded/bg-loaded.js

So just include the plugin and then call it on the element:

<script type="text/javascript" src="http://catmull.uk/downloads/bg-loaded/bg-loaded.js"></script>
<script type="text/javascript">
   $('body').bgLoaded();
</script>

Obviously download the plugin and store it on your own hosting.

By default it adds an additional "bg-loaded" class to each matched element once the background is loaded but you can easily change that by passing it a different function like this:

<script type="text/javascript" src="http://catmull.uk/downloads/bg-loaded/bg-loaded.js"></script>
<script type="text/javascript">
   $('body').bgLoaded({
      afterLoaded : function() {
         alert('Background image done loading');
      }
   });
</script>

Here is a codepen demonstrating it working.

http://codepen.io/catmull/pen/Lfcpb

Solution 7 - Javascript

I've located a solution that worked better for me, and which has the advantage of being usable with several images (case not illustrated in this example).

From @adeneo's answer on this question :

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

> > 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();

Solution 8 - Javascript

I did a pure javascript hack to make this possible.

<div class="my_background_image" style="background-image: url(broken-image.jpg)">
<img class="image_error" src="broken-image.jpg" onerror="this.parentElement.style.display='none';">
</div>

Or

onerror="this.parentElement.backgroundImage = "url('image_placeHolder.png')";

css:

.image_error {
    display: none;
}

Solution 9 - Javascript

https://github.com/alexanderdickson/waitForImages

$('selector').waitForImages({
    finished: function() {
       // ...
    },
    each: function() {
       // ...
    },
    waitForAll: true
});

Solution 10 - Javascript

Here is a simple vanilla hack ~

(function(image){
  image.onload = function(){ 
                   $(body).addClass('loaded-background');
                   alert('Background image done loading');
                   // TODO fancy fade-in
                 };
  image.src    = "http://picture.de/image.png";
})(new Image());

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPeterView Question on Stackoverflow
Solution 1 - JavascriptjcubicView Answer on Stackoverflow
Solution 2 - JavascriptalexView Answer on Stackoverflow
Solution 3 - JavascriptAdrian PacalaView Answer on Stackoverflow
Solution 4 - JavascriptColinView Answer on Stackoverflow
Solution 5 - JavascriptgodblessstrawberryView Answer on Stackoverflow
Solution 6 - JavascriptJon CatmullView Answer on Stackoverflow
Solution 7 - JavascriptPaperjuiceView Answer on Stackoverflow
Solution 8 - JavascriptGinoView Answer on Stackoverflow
Solution 9 - JavascriptyazabaraView Answer on Stackoverflow
Solution 10 - JavascriptredolentView Answer on Stackoverflow