📜 ⬆️ ⬇️

Making a full-fledged JS preloader for an AJAX application

Many programmers optimize JavaScript and CSS code to make the page load faster.
But not all of them make preloaders that give the user the effect of subjectively faster loading.

Method number 1. Cheap and angry.
The idea is simple - you need to put a picture in the center that will show the user that the page is still loading. The code is pretty simple; we write right after <body>:

< div id ="preloaderbg" class ="centerbg1" > < div class ="centerbg2" > < div id ="preloader" ></ div > </ div > </ div > < script type ="text/javascript" > document .getElementById( 'preloaderbg' ).style.display = 'block' ; document .body.style.overflow = 'hidden' ; </ script > * This source code was highlighted with Source Code Highlighter .
  1. < div id ="preloaderbg" class ="centerbg1" > < div class ="centerbg2" > < div id ="preloader" ></ div > </ div > </ div > < script type ="text/javascript" > document .getElementById( 'preloaderbg' ).style.display = 'block' ; document .body.style.overflow = 'hidden' ; </ script > * This source code was highlighted with Source Code Highlighter .
  2. < div id ="preloaderbg" class ="centerbg1" > < div class ="centerbg2" > < div id ="preloader" ></ div > </ div > </ div > < script type ="text/javascript" > document .getElementById( 'preloaderbg' ).style.display = 'block' ; document .body.style.overflow = 'hidden' ; </ script > * This source code was highlighted with Source Code Highlighter .
  3. < div id ="preloaderbg" class ="centerbg1" > < div class ="centerbg2" > < div id ="preloader" ></ div > </ div > </ div > < script type ="text/javascript" > document .getElementById( 'preloaderbg' ).style.display = 'block' ; document .body.style.overflow = 'hidden' ; </ script > * This source code was highlighted with Source Code Highlighter .
  4. < div id ="preloaderbg" class ="centerbg1" > < div class ="centerbg2" > < div id ="preloader" ></ div > </ div > </ div > < script type ="text/javascript" > document .getElementById( 'preloaderbg' ).style.display = 'block' ; document .body.style.overflow = 'hidden' ; </ script > * This source code was highlighted with Source Code Highlighter .
  5. < div id ="preloaderbg" class ="centerbg1" > < div class ="centerbg2" > < div id ="preloader" ></ div > </ div > </ div > < script type ="text/javascript" > document .getElementById( 'preloaderbg' ).style.display = 'block' ; document .body.style.overflow = 'hidden' ; </ script > * This source code was highlighted with Source Code Highlighter .
  6. < div id ="preloaderbg" class ="centerbg1" > < div class ="centerbg2" > < div id ="preloader" ></ div > </ div > </ div > < script type ="text/javascript" > document .getElementById( 'preloaderbg' ).style.display = 'block' ; document .body.style.overflow = 'hidden' ; </ script > * This source code was highlighted with Source Code Highlighter .
  7. < div id ="preloaderbg" class ="centerbg1" > < div class ="centerbg2" > < div id ="preloader" ></ div > </ div > </ div > < script type ="text/javascript" > document .getElementById( 'preloaderbg' ).style.display = 'block' ; document .body.style.overflow = 'hidden' ; </ script > * This source code was highlighted with Source Code Highlighter .
  8. < div id ="preloaderbg" class ="centerbg1" > < div class ="centerbg2" > < div id ="preloader" ></ div > </ div > </ div > < script type ="text/javascript" > document .getElementById( 'preloaderbg' ).style.display = 'block' ; document .body.style.overflow = 'hidden' ; </ script > * This source code was highlighted with Source Code Highlighter .
  9. < div id ="preloaderbg" class ="centerbg1" > < div class ="centerbg2" > < div id ="preloader" ></ div > </ div > </ div > < script type ="text/javascript" > document .getElementById( 'preloaderbg' ).style.display = 'block' ; document .body.style.overflow = 'hidden' ; </ script > * This source code was highlighted with Source Code Highlighter .
< div id ="preloaderbg" class ="centerbg1" > < div class ="centerbg2" > < div id ="preloader" ></ div > </ div > </ div > < script type ="text/javascript" > document .getElementById( 'preloaderbg' ).style.display = 'block' ; document .body.style.overflow = 'hidden' ; </ script > * This source code was highlighted with Source Code Highlighter .


CSS code:
')
  1. .centerbg1 {
  2. display: none;
  3. width: 100%;
  4. height: 100%;
  5. position: absolute;
  6. top: 0px;
  7. left: 0px;
  8. z-index: 1000;
  9. background: url ( '/design/im/texture1.jpg' ) # 3c363e;
  10. }
  11. .centerbg2 {
  12. position: absolute;
  13. left: 50%;
  14. top: 50%;
  15. }
  16. #preloader {
  17. top: -50%;
  18. left: -50%;
  19. position: relative;
  20. width: 333px;
  21. height: 26px;
  22. background: url ( '/content/pages/articles/preloaders/bg2.gif' );
  23. border: solid # edda3d 2px;
  24. }
* This source code was highlighted with Source Code Highlighter .


As a result, right after the download, we have a block with an animated progress bar in the center of the page. The overflow parameter needs to be changed so that the scroll bar does not appear and the user cannot scroll down and look at the contents of the page.

Then, when everything is loaded - you need to remove the preloader and set the overflow to the visible position.

  1. document .getElementById ( 'loaderbg' ) .style.display = 'none' ;
  2. document .body.style.overflow = 'visible' ;
* This source code was highlighted with Source Code Highlighter .


I put this part of the code in a file with JS-functions, plreloader1.js

If you make a progress bar from an animated GIF-image, it can turn out too heavy, sometimes even more than the page where it is placed.
Therefore, it is better to draw a strip (for example, such ), put it as a background at the block with the ID preloader and move the background-position on the timer.

  1. <script type = "text / javascript" >
  2. document .getElementById ( 'loaderbg' ) .style.display = 'block' ;
  3. document .body.style.overflow = 'hidden' ;
  4. pbPos = 0;
  5. pbInt = setInterval ( function () {
  6. document .getElementById ( 'preloader' ) .style.backgroundPosition = ++ pbPos + 'px 0' ;
  7. }, 25);
  8. </ script>
* This source code was highlighted with Source Code Highlighter .


And after loading we do this:
  1. clearInterval (pbPos);
  2. document .getElementById ( 'loaderbg' ) .style.display = 'none' ;
* This source code was highlighted with Source Code Highlighter .


The result of the work can be found here .

This method has drawbacks - If you set the preloader to hide on onload, i.e. when to wait until all the pictures are loaded, the user may think that the page just hung - in fact, nothing happens except animation. If you hang on $ (document). Ready () from jQuery, then after the preloader disappears, the pictures will only be loaded.

Therefore it is proposed to use ...

Method number 2. Truth is somewhere near, or the Jedi strike back.
To begin with we will draw 2 load bands - active and not very.

Inactive bar
Active band

We will set the inactive background, and the active background will be made by the diva, for which we will change the width depending on the load percentage.

  1. < div id = "loaderbg" class = "centerbg1" >
  2. < div class = "centerbg2" >
  3. < div id = "preloader" >
  4. < img alt = "Loading ..." src = "/ design / im / progbar_ph.gif" />
  5. < div id = "progbarfg" > </ div >
  6. </ div >
  7. </ div >
  8. </ div >
* This source code was highlighted with Source Code Highlighter .


progbar_ph.gif is a picture 1 pixel high and wide with our scroll bar (this example is buggy without it in IE, and I haven’t yet found another way to center the divs with the progress bar).
The styles are the same as in the previous method, except
#progbarfg {width: 0px; background: url('/design/im/progbar_fg.png')}


Now it remains to make a small script that will dynamically load the site contents and images. It is needed so that the progress bar is displayed and changed before the used framework and other JS files are downloaded.

Take an average site made entirely on AJAX. Download approximately happens as follows:

All this (minus CSS and HTML) we assign the weight in bytes (or conditional weight), for example, one, and as we load each file (or function), we move our progress bar.

I implemented 2 methods - the first is simple, it turns on like this:
immediately before </ body> we write:

< script type ="text/javascript" >
dLoader.start( 'progbarfg' , 333, 'count' );
</ script >


The first parameter is the block identifier with the active loading bar as a background, the second is the width of the image, the third parameter is the method by which we will consider the weight of the content.

The script scans all the pictures on the pages and assigns them a weight equal to 1. All JS-files are written in his body, as I will describe below.
However, it would be desirable that the weight of each unit of content was not a unit, but a real volume in bytes. Yes, and for AJAX-applications I would like to immediately load the entire schedule.

To do this, I wrote a PHP script that scans the folder with the artwork and brings the whole file size into an array, optionally compressing it.

So by adding the following before </ body>, we will get a progress bar that will show the progress of loading all the content on the page, after which it will disappear smoothly.

  1. <script type = "text / javascript" >
  2. dLoader.start ( 'mainprogbarfg' , 333, 'size' , function () {$ ( '#preloaderbg' ) .fadeOut (250);});
  3. </ script>
* This source code was highlighted with Source Code Highlighter .


When all JS-files are loaded, the functions that are in the invoke array are launched. If we use the jQuery to load the content, the function will look like this:

  1. function fn (callBack) {
  2. $ .get ( '/' , params , function (data) {someHandler (data); eval (callBack);});
  3. }
* This source code was highlighted with Source Code Highlighter .


The PHP script does the following: it puts the necessary scripts with their sizes, as well as images and additional functions into the array. Code:

  1. $ data [ 'js' ] = array (
  2. array ( 'path' => 'jquery-1.2.6.min.js' , 'size' => filesize ($ jsRoot. '/jquery-1.2.6.min.js' )),
  3. array ( 'path' => 'functions.js' , 'size' => filesize ($ jsRoot. '/functions.js' ))
  4. );
  5. $ data [ 'im' ] = GetFiles ($ imgRoot, true );
  6. $ data [ 'invoke' ] [] = array (
  7. 'action' => 'loadTemplates' ,
  8. 'size' => GetDirSize (dirname (__ FILE__). '/ design / ajax templates /' , false )
  9. );
  10. $ data [ 'jspath' ] = '/ design / js /' ;
  11. $ data [ 'impath' ] = '/ design / im' ;
* This source code was highlighted with Source Code Highlighter .


Already after all the pictures and JS-files are loaded, the onLoad event is triggered, which you specified in the dLoader.start () function

There is still a way to customize the boot process:

  1. dLoader.userProgress = function (bytesLoaded, totalBytes) {doSmth (); }
* This source code was highlighted with Source Code Highlighter .


In order to use this, you need to edit the PHP script, register your paths and JS libraries in it, then run it so that it generates a bootloader script, which you then need to register in <head> with a single script.
A working example of the second option is here .

Archive with scripts can be taken from here , but to see how it all works - on my website .

Works in Internet Explorer 6/7, Firefox 3, Opera 9.5, Safari 3.2.1

Suggestions and suggestions are welcome :)

Thanks for the help in preparing the article waitekk pour out his karma and I still have herbs

Source: https://habr.com/ru/post/46210/


All Articles