8

I'm having trouble finding any good information on how to make a javascript(or jquery) progress bar WITH text that tells you the percentage.

I don't want a plug in, I just want to know how it works so that I can adapt it to what I need. How do you preload images and get a variable for the number of images that are preloaded. Also, how do you change html/css and-or call a function, based on the number of images that are loaded already?

heckascript
  • 2,034
  • 3
  • 22
  • 39
  • please refer this question http://stackoverflow.com/questions/49564/how-to-implement-file-upload-progress-bar-on-web – sundar nataraj Mar 12 '13 at 06:25
  • 2
    that doesn't answer my question at all... it just provides two links to plug-ins, one of which doesn't even work. Like I said, I want to understand how the actual code works with javascript to preload a number of images, then set that number as a variable, and do different things based on when that variable reaches certain points. One of those things being, giving a readout of the percentage of all images that are loaded. Another being developing my own load bar, and possibly even triggering animations (made with adobe edge) to play. – heckascript Mar 12 '13 at 06:37

2 Answers2

7

<img> elements have an onload event that fires once the image has fully loaded. Therefore, in js you can keep track of the number of images that have loaded vs the number remaining using this event.

Images also have corresponding onerror and onabort events that fire when the image fails to load or the download have been aborted (by the user pressing the 'x' button). You also need to keep track of them along with the onload event to keep track of image loading properly.


Additional answer:

A simple example in pure js:

var img_to_load = [ '/img/1.jpg', '/img/2.jpg' ];
var loaded_images = 0;

for (var i=0; i<img_to_load.length; i++) {
    var img = document.createElement('img');
    img.src = img_to_load[i];
    img.style.display = 'hidden'; // don't display preloaded images
    img.onload = function () {
        loaded_images ++;
        if (loaded_images == img_to_load.length) {
            alert('done loading images');
        }
        else {
            alert((100*loaded_images/img_to_load.length) + '% loaded');
        }
    }
    document.body.appendChild(img);
}

The example above doesn't handle onerror or onabort for clarity but real world code should take care of them as well.

slebetman
  • 93,070
  • 18
  • 116
  • 145
  • what would the syntax look like for something like this: 1. Find the number of img's to be loaded. 2. begin loading those images. 3. Tell me the percentage of images loaded based on the total number of img's being equal to 100%. 4. onload, if percentage of images = 25% then do something, else 50%, else 75%, etc... – heckascript Mar 12 '13 at 06:58
  • 1
    1. Find the number of img to be loaded: this you should know before hand right? You're the one loading/preloading the images after all. – slebetman Mar 12 '13 at 07:20
  • 1
    2. HTML can only load images 2 ways: using img tag or as background image of elements. So that's how you begin loading images - create img elements or create divs/spans and set their background. Preloading works because browsers will even load images that are hidden. – slebetman Mar 12 '13 at 07:22
  • lol sorry, that should have been more obvious to me. What I mean is just how do I have javascript find the number of images to load? – heckascript Mar 12 '13 at 07:24
  • 1
    You need to clarify what finding the number of images to load mean. Searching for all img tags in the DOM? I thought this was about preloading images. – slebetman Mar 12 '13 at 07:33
  • yeah, all images in the document... is it just document.images? – heckascript Mar 12 '13 at 07:38
  • what does the 'document.body.appendChild(img);' do? because the code is working fine without it... – heckascript Mar 12 '13 at 08:44
  • 1
    I was assuming you were preloading the images - not dynamic loading them. Preloading means loading images that is not in the page yet but may be inserted into the page some time in the future. The technique is to add hidden img tags to the page to force the browser to cache the images that you want to insert later (like icons in menus etc). – slebetman Mar 12 '13 at 08:48
  • 1
    What you're doing instead is allow the page to function before all images are loaded and load the images in the background. That's not preloading. Different people have different names for it but I call it dynamic loading. – slebetman Mar 12 '13 at 08:50
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/26011/discussion-between-user1868084-and-slebetman) – heckascript Mar 12 '13 at 09:14
  • Although it's unnecessary, I think it would be good practise delete all the images when they are preloaded. – dgnin Feb 28 '14 at 08:32
3

What about using something below:

$('#btnUpload').click(function() {
    var bar = document.getElementById('progBar'),
        fallback = document.getElementById('downloadProgress'),
        loaded = 0;

    var load = function() {
        loaded += 1;
        bar.value = loaded;

        /* The below will be visible if the progress tag is not supported */
        $(fallback).empty().append("HTML5 progress tag not supported: ");
        $('#progUpdate').empty().append(loaded + "% loaded");

        if (loaded == 100) {
            clearInterval(beginLoad);
            $('#progUpdate').empty().append("Upload Complete");
            console.log('Load was performed.');
        }
    };

    var beginLoad = setInterval(function() {
        load();
    }, 50);

});

JSFIDDLE

You might also want to try HTML5 progress element:

<section>
<p>Progress: <progress id="p" max=100><span>0</span>%</progress></p>

<script>
var progressBar = document.getElementById('p');

function updateProgress(newValue) {
progressBar.value = newValue;
progressBar.getElementsByTagName('span')[0].textContent = newValue;
} </script>
</section> 

http://www.html5tutorial.info/html5-progress.php

defau1t
  • 10,373
  • 2
  • 32
  • 45
  • 1
    How would I do that with a given number of images though? instead of just an animation of a set length... I have 41 images that I need to preload. – heckascript Mar 12 '13 at 06:42
  • also the html5 progress element doesn't seem to be supported by all browsers, I am trying to make something that will work for all devices and browsers. – heckascript Mar 12 '13 at 06:45