[javascript] How to display a loading screen while site content loads

I'm working on a site which contains a whole bunch of mp3s and images, and I'd like to display a loading gif while all the content loads.

I have no idea how to achieve this, but I do have the animated gif I want to use.

Any suggestions?

This question is related to javascript html css loading pageload

The answer is


Typically sites that do this by loading content via ajax and listening to the readystatechanged event to update the DOM with a loading GIF or the content.

How are you currently loading your content?

The code would be similar to this:

function load(url) {
    // display loading image here...
    document.getElementById('loadingImg').visible = true;
    // request your data...
    var req = new XMLHttpRequest();
    req.open("POST", url, true);

    req.onreadystatechange = function () {
        if (req.readyState == 4 && req.status == 200) {
            // content is loaded...hide the gif and display the content...
            if (req.responseText) {
                document.getElementById('content').innerHTML = req.responseText;
                document.getElementById('loadingImg').visible = false;
            }
        }
    };
    request.send(vars);
}

There are plenty of 3rd party javascript libraries that may make your life easier, but the above is really all you need.


First, set up a loading image in a div. Next, get the div element. Then, set a function that edits the css to make the visibility to "hidden". Now, in the <body>, put the onload to the function name.


#Pure css method

Place this at the top of your code (before header tag)

_x000D_
_x000D_
<style> .loader {_x000D_
  position: fixed;_x000D_
  background-color: #FFF;_x000D_
  opacity: 1;_x000D_
  height: 100%;_x000D_
  width: 100%;_x000D_
  top: 0;_x000D_
  left: 0;_x000D_
  z-index: 10;_x000D_
}_x000D_
</style>
_x000D_
<div class="loader">_x000D_
  Your Content For Load Screen_x000D_
</div>
_x000D_
_x000D_
_x000D_

And This At The Bottom after all other code (except /html tag)

_x000D_
_x000D_
<style>_x000D_
.loader {_x000D_
    -webkit-animation: load-out 1s;_x000D_
    animation: load-out 1s;_x000D_
    -webkit-animation-fill-mode: forwards;_x000D_
    animation-fill-mode: forwards;_x000D_
}_x000D_
_x000D_
@-webkit-keyframes load-out {_x000D_
    from {_x000D_
        top: 0;_x000D_
        opacity: 1;_x000D_
    }_x000D_
_x000D_
    to {_x000D_
        top: 100%;_x000D_
        opacity: 0;_x000D_
    }_x000D_
}_x000D_
_x000D_
@keyframes load-out {_x000D_
    from {_x000D_
        top: 0;_x000D_
        opacity: 1;_x000D_
    }_x000D_
_x000D_
    to {_x000D_
        top: 100%;_x000D_
        opacity: 0;_x000D_
    }_x000D_
}_x000D_
</style>
_x000D_
_x000D_
_x000D_

This always works for me 100% of the time


First, set up a loading image in a div. Next, get the div element. Then, set a function that edits the css to make the visibility to "hidden". Now, in the <body>, put the onload to the function name.


You can use <progress> element in HTML5. See this page for source code and live demo. http://purpledesign.in/blog/super-cool-loading-bar-html5/

here is the progress element...

<progress id="progressbar" value="20" max="100"></progress>

this will have the loading value starting from 20. Of course only the element wont suffice. You need to move it as the script loads. For that we need JQuery. Here is a simple JQuery script that starts the progress from 0 to 100 and does something in defined time slot.

<script>
        $(document).ready(function() {
         if(!Modernizr.meter){
         alert('Sorry your brower does not support HTML5 progress bar');
         } else {
         var progressbar = $('#progressbar'),
         max = progressbar.attr('max'),
         time = (1000/max)*10, 
         value = progressbar.val();
        var loading = function() {
        value += 1;
        addValue = progressbar.val(value);
        $('.progress-value').html(value + '%');
        if (value == max) {
        clearInterval(animate);
        //Do Something
 }
if (value == 16) {
//Do something 
}
if (value == 38) {
//Do something
}
if (value == 55) {
//Do something 
}
if (value == 72) {
//Do something 
}
if (value == 1) {
//Do something 
}
if (value == 86) {
//Do something 
    }

};
var animate = setInterval(function() {
loading();
}, time);
};
});
</script>

Add this to your HTML file.

<div class="demo-wrapper html5-progress-bar">
<div class="progress-bar-wrapper">
 <progress id="progressbar" value="0" max="100"></progress>
 <span class="progress-value">0%</span>
</div>
 </div>

Hope this will give you a start.


You said you didn't want to do this in AJAX. While AJAX is great for this, there is a way to show one DIV while waiting for the entire <body> to load. It goes something like this:

<html>
  <head>
    <style media="screen" type="text/css">
      .layer1_class { position: absolute; z-index: 1; top: 100px; left: 0px; visibility: visible; }
      .layer2_class { position: absolute; z-index: 2; top: 10px; left: 10px; visibility: hidden }
    </style>
    <script>
      function downLoad(){
        if (document.all){
            document.all["layer1"].style.visibility="hidden";
            document.all["layer2"].style.visibility="visible";
        } else if (document.getElementById){
            node = document.getElementById("layer1").style.visibility='hidden';
            node = document.getElementById("layer2").style.visibility='visible';
        }
      }
    </script>
  </head>
  <body onload="downLoad()">
    <div id="layer1" class="layer1_class">
      <table width="100%">
        <tr>
          <td align="center"><strong><em>Please wait while this page is loading...</em></strong></p></td>
        </tr>
      </table>
    </div>
    <div id="layer2" class="layer2_class">
        <script type="text/javascript">
                alert('Just holding things up here.  While you are reading this, the body of the page is not loading and the onload event is being delayed');
        </script>
        Final content.      
    </div>
  </body>
</html>

The onload event won't fire until all of the page has loaded. So the layer2 <DIV> won't be displayed until the page has finished loading, after which onload will fire.


How about with jQuery? A simple...

$(window).load(function() {      //Do the code in the {}s when the window has loaded 
  $("#loader").fadeOut("fast");  //Fade out the #loader div
});

And the HTML...

<div id="loader"></div>

And CSS...

#loader {
      width: 100%;
      height: 100%;
      background-color: white;
      margin: 0;
}

Then in your loader div you would put the GIF, and any text you wanted, and it will fade out once the page has loaded.


There's actually a pretty easy way to do this. The code should be something like:

<script type="test/javascript">

    function showcontent(x){

      if(window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
      } else {
        xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
      }

      xmlhttp.onreadystatechange = function() {
        if(xmlhttp.readyState == 1) {
            document.getElementById('content').innerHTML = "<img src='loading.gif' />";
        }
        if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
          document.getElementById('content').innerHTML = xmlhttp.responseText;
        } 
      }

      xmlhttp.open('POST', x+'.html', true);
      xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');
      xmlhttp.send(null);

    }

And in the HTML:

<body onload="showcontent(main)"> <!-- onload optional -->
<div id="content"><img src="loading.gif"></div> <!-- leave img out if not onload -->
</body>

I did something like that on my page and it works great.


You can use <progress> element in HTML5. See this page for source code and live demo. http://purpledesign.in/blog/super-cool-loading-bar-html5/

here is the progress element...

<progress id="progressbar" value="20" max="100"></progress>

this will have the loading value starting from 20. Of course only the element wont suffice. You need to move it as the script loads. For that we need JQuery. Here is a simple JQuery script that starts the progress from 0 to 100 and does something in defined time slot.

<script>
        $(document).ready(function() {
         if(!Modernizr.meter){
         alert('Sorry your brower does not support HTML5 progress bar');
         } else {
         var progressbar = $('#progressbar'),
         max = progressbar.attr('max'),
         time = (1000/max)*10, 
         value = progressbar.val();
        var loading = function() {
        value += 1;
        addValue = progressbar.val(value);
        $('.progress-value').html(value + '%');
        if (value == max) {
        clearInterval(animate);
        //Do Something
 }
if (value == 16) {
//Do something 
}
if (value == 38) {
//Do something
}
if (value == 55) {
//Do something 
}
if (value == 72) {
//Do something 
}
if (value == 1) {
//Do something 
}
if (value == 86) {
//Do something 
    }

};
var animate = setInterval(function() {
loading();
}, time);
};
});
</script>

Add this to your HTML file.

<div class="demo-wrapper html5-progress-bar">
<div class="progress-bar-wrapper">
 <progress id="progressbar" value="0" max="100"></progress>
 <span class="progress-value">0%</span>
</div>
 </div>

Hope this will give you a start.


You said you didn't want to do this in AJAX. While AJAX is great for this, there is a way to show one DIV while waiting for the entire <body> to load. It goes something like this:

<html>
  <head>
    <style media="screen" type="text/css">
      .layer1_class { position: absolute; z-index: 1; top: 100px; left: 0px; visibility: visible; }
      .layer2_class { position: absolute; z-index: 2; top: 10px; left: 10px; visibility: hidden }
    </style>
    <script>
      function downLoad(){
        if (document.all){
            document.all["layer1"].style.visibility="hidden";
            document.all["layer2"].style.visibility="visible";
        } else if (document.getElementById){
            node = document.getElementById("layer1").style.visibility='hidden';
            node = document.getElementById("layer2").style.visibility='visible';
        }
      }
    </script>
  </head>
  <body onload="downLoad()">
    <div id="layer1" class="layer1_class">
      <table width="100%">
        <tr>
          <td align="center"><strong><em>Please wait while this page is loading...</em></strong></p></td>
        </tr>
      </table>
    </div>
    <div id="layer2" class="layer2_class">
        <script type="text/javascript">
                alert('Just holding things up here.  While you are reading this, the body of the page is not loading and the onload event is being delayed');
        </script>
        Final content.      
    </div>
  </body>
</html>

The onload event won't fire until all of the page has loaded. So the layer2 <DIV> won't be displayed until the page has finished loading, after which onload will fire.


How about with jQuery? A simple...

$(window).load(function() {      //Do the code in the {}s when the window has loaded 
  $("#loader").fadeOut("fast");  //Fade out the #loader div
});

And the HTML...

<div id="loader"></div>

And CSS...

#loader {
      width: 100%;
      height: 100%;
      background-color: white;
      margin: 0;
}

Then in your loader div you would put the GIF, and any text you wanted, and it will fade out once the page has loaded.


#Pure css method

Place this at the top of your code (before header tag)

_x000D_
_x000D_
<style> .loader {_x000D_
  position: fixed;_x000D_
  background-color: #FFF;_x000D_
  opacity: 1;_x000D_
  height: 100%;_x000D_
  width: 100%;_x000D_
  top: 0;_x000D_
  left: 0;_x000D_
  z-index: 10;_x000D_
}_x000D_
</style>
_x000D_
<div class="loader">_x000D_
  Your Content For Load Screen_x000D_
</div>
_x000D_
_x000D_
_x000D_

And This At The Bottom after all other code (except /html tag)

_x000D_
_x000D_
<style>_x000D_
.loader {_x000D_
    -webkit-animation: load-out 1s;_x000D_
    animation: load-out 1s;_x000D_
    -webkit-animation-fill-mode: forwards;_x000D_
    animation-fill-mode: forwards;_x000D_
}_x000D_
_x000D_
@-webkit-keyframes load-out {_x000D_
    from {_x000D_
        top: 0;_x000D_
        opacity: 1;_x000D_
    }_x000D_
_x000D_
    to {_x000D_
        top: 100%;_x000D_
        opacity: 0;_x000D_
    }_x000D_
}_x000D_
_x000D_
@keyframes load-out {_x000D_
    from {_x000D_
        top: 0;_x000D_
        opacity: 1;_x000D_
    }_x000D_
_x000D_
    to {_x000D_
        top: 100%;_x000D_
        opacity: 0;_x000D_
    }_x000D_
}_x000D_
</style>
_x000D_
_x000D_
_x000D_

This always works for me 100% of the time


There's actually a pretty easy way to do this. The code should be something like:

<script type="test/javascript">

    function showcontent(x){

      if(window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
      } else {
        xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
      }

      xmlhttp.onreadystatechange = function() {
        if(xmlhttp.readyState == 1) {
            document.getElementById('content').innerHTML = "<img src='loading.gif' />";
        }
        if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
          document.getElementById('content').innerHTML = xmlhttp.responseText;
        } 
      }

      xmlhttp.open('POST', x+'.html', true);
      xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');
      xmlhttp.send(null);

    }

And in the HTML:

<body onload="showcontent(main)"> <!-- onload optional -->
<div id="content"><img src="loading.gif"></div> <!-- leave img out if not onload -->
</body>

I did something like that on my page and it works great.


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to loading

JavaScript Loading Screen while page loads How to add a spinner icon to button when it's in the Loading state? Display a loading bar before the entire page is loaded WPF loading spinner Using the "animated circle" in an ImageView while loading stuff Display loading image while post with ajax Running sites on "localhost" is extremely slow open resource with relative path in Java Dynamic loading of images in WPF How to create a JavaScript callback for knowing when an image is loaded?

Examples related to pageload

Auto-click button element on page load using jQuery Force page scroll position to top at page refresh in HTML How to make JavaScript execute after page load? $(document).ready equivalent without jQuery How to display a loading screen while site content loads Is there a cross-browser onload event when clicking the back button?