Preloading CSS background images with javascript

A vanilla JS script I wrote to preload background images and trigger a callback function once loaded into the DOM.

Last updated on 19 August, 2018, 1:33pm by keston


UPDATE: 19/8/18 - I've added a condition to the getAllBackgroundImages function to display console errors for any missing background images, while your developing - to help speed up debugging.


This is a script I wrote to create a standard 'load' event for image assets implemented as background images via CSS. The script essentially looks for html elements with a 'preload' class (which you include on relevant elements), saves query results in an array and outputs each element in a hidden container in the DOM in a img tag - so we can listen for the img load event.


I currently use this script to check that banner assets have fully loaded before triggering main animation. 

The Javascript

function imageBgPreload(onComplete) {
    // preload all background images
    try {
        console.log("preload try successful");
    catch(err) {
        console.log("preload skipped");
        function runBgPreload(onComplete) {
        var imageHolder = document.createElement("div");
        imageHolder.setAttribute("id", "preBgHolder"); = "none";
        var preloads = document.getElementsByClassName("preload");
        var imageBank = document.getElementById("preBgHolder");
        var preloadUrls = [];
        var images = [];
        var pre = [];
        var preStatus = [];
        var allImagesReady;
        var onCompleteFired = false;
        // grab all background images from CSS and preload in a CSS hidden div called preBgHolder.
        function getAllBackgroundImages() {
            for (i = 0; i < preloads.length; i++) {
                    if (window.getComputedStyle(preloads[i]).getPropertyValue("background-image") != "none") {
                        preloadUrls[i] = window.getComputedStyle(preloads[i]).getPropertyValue("background-image");
                    preloadUrls[i] = preloadUrls[i].replace(/\"/g, ''); // removes url quotes as computed different in safari
                    preloadUrls[i] = preloadUrls[i].substring(4, preloadUrls[i].length - 1);
                    images[i] = new Image();
                    images[i].src = preloadUrls[i];
                    } else {
                        console.error( "#" + preloads[i].id + " does not contain a background image");
        // check each img tag in the hidden div has loaded
        function statusListeners() {
            pre = document.getElementsByClassName("preBg");
            for (i = 0; i < pre.length; i++) {
                pre[i].addEventListener("load", checkEachStatus, false);
                preStatus[i] = pre[i].complete;
                //console.log([i] + " load status: " + preStatus[i]);

        function checkEachStatus() {
            function imageLoadedTrue(loadStatuses) {
                return loadStatuses == true;
            for (i = 0; i < pre.length; i++) {
                preStatus[i] = pre[i].complete;
                //console.log(pre[i].complete + i);
                allImagesReady = preStatus.every(imageLoadedTrue);
                if (allImagesReady == true && onCompleteFired == false) {
                    // mainFired used to stop runMain firing more than once if images load from cache
                    onCompleteFired = true;
        // if there are no preloads to work with run the fallack function anyway
        if (preloads.length == 0) {
            console.log("there was nothing to preload");


 <!DOCTYPE html>
 <meta charset="utf-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
 <title >Check whether background images have loaded </title>
 <meta name="description" content="">
 <meta name="viewport" content="width=device-width">
 <link rel="stylesheet" href="styles.css">

          <div id="mainContent">
             <div id="image1" class="preload"> </div>
             <div id="image2" class="preload"> </div>
             <div id="image3" class="preload"> </div>
             <div id="image4" class="preload"> </div>

 <script src="bgPreload.js"> </script>

    function onceLoaded(){
        // this callback function could be a script from any other file etc
        //console.log("onceLoaded fired");
        var mainContent = document.getElementById("mainContent");     = 1; = "visible"; = "50px";