Skip to content

Instantly share code, notes, and snippets.

@Gergling
Created May 23, 2013 15:57
Show Gist options
  • Save Gergling/5637147 to your computer and use it in GitHub Desktop.
Save Gergling/5637147 to your computer and use it in GitHub Desktop.
This is a requirejs-based preloader progress bar using jquery. Download the files into a directory and run index.html in a browser to see the effects.
<html>
<head>
<!-- Use the stylesheet provided as an example of how to style the progressbar. -->
<link rel="stylesheet" type="text/css" href="progressbar-style.css" />
<!-- The requirejs package is needed for the preloader to run.-->
<script src="requirejs.js"></script>
<!-- The guts for loading and event management are handled in this file. -->
<script src="PackageLoader.js"></script>
</head>
<body>
<script type="text/javascript">
// This triggers the load sequence.
PackageLoader.instance.load({
// These frameworks are required for the preloader to run.
preloader: "PackagePreloader.js",
jQuery: "https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js",
domParent: document.body,
}, {
// These packages are not necessary to the running of the preloader, but have been used in this example.
// In this example, base packages 2 is backbone - reliant on the loading of underscore in base packages 1. Each set of packages begins loading when the previous set has loaded.
// The keys act as labels for the listing of currently loading packages.
"Base Packages 1": [
"https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js",
"https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js",
],
"Base Packages 2": [
"https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js",
],
}, function() {
// On load, this function is run. This could be used to load a single-page app.
$('body').html("Ta-da!");
});
</script>
</body>
</html>
var PackageLoader = function() {
this.cb = Math.random(0, 100000000000);
this.current = 0;
this.batches = [];
// Load kicks off the entire loading process.
this.load = function(config, loadMap, onload) {
var scope = this;
for(label in loadMap) {
scope.batches.push(new PackageBatch(label, loadMap[label]));
}
scope.onload = onload;
if (config.preloader && config.jQuery) {
requirejs([
config.preloader,
config.jQuery
], function() {
PackagePreloader.instance.init(config);
scope._subLoad();
});
} else {
console.error("PackageLoader.load: First argument (config object) requires 'preloader' and 'jQuery' source path properties, or the function cannot run.");
}
};
// This loads the current (not-yet-loaded) batch of packages.
this._subLoad = function() {
PackagePreloader.instance.update();
var scope = this;
if (this.current<this.batches.length) {
this.batches[this.current].require(function() {
scope.current++;
scope._subLoad();
});
} else {
$(function() {
PackagePreloader.instance.complete(scope.onload);
});
}
};
// Returns the current package. The point of this is to be a neat public function.
this.getCurrentPackage = function() {
return this.batches[this.current];
};
};
// This is currently automatically a singleton, until a better method of defining the PackageLoader/PackagePreloader relationship is defined.
PackageLoader.instance = new PackageLoader();
// Handles a single 'batch' of packages.
var PackageBatch = function(label, batch) {
this.label = label;
this.batch = batch;
this.require = function(complete) {
requirejs(this.batch, complete);
};
};
var PackagePreloader = function() {
this.el = document.createElement('div');
this.jqBar;
// Initially called with PackageLoader config.
this.init = function(config) {
if (config.domParent) {
$(this.el).appendTo(config.domParent);
this.jqBar = $('<div>')
.css('width',0)
.addClass("progressbar-progress")
;
this.$loadList = $('<ul>').addClass('package-listing').css('width', '600px').css('margin', '0 auto').html("Loading...");
$(this.el).append(
$('<div>').append(
$('<div>')
.css('background-color', 'transparent')
.append(this.jqBar)
.addClass("progressbar-inner")
).addClass("progressbar")
).append(this.$loadList);
} else {
console.error("PackagePreloader.init: Config object requires 'domParent' property. This property must contain the parent dom object to which the progress bar will be attached. Otherwise the function cannot run.");
}
};
// Returns the fraction current progress.
this.interpretCurrent = function() {
return PackageLoader.instance.current/PackageLoader.instance.batches.length;
};
// Called each time a batch is loaded and the current batch to be loaded is updated.
this.update = function() {
this.jqBar.css('width', (this.interpretCurrent()*100)+'%');
var pkg = PackageLoader.instance.getCurrentPackage();
if (pkg) {
this.$loadList.append($('<li>').html("Loaded "+pkg.label));
}
};
// Fades out when done.
this.complete = function(onFadeOut) {
$(this.el).fadeOut({complete:onFadeOut});
};
};
PackagePreloader.instance = new PackagePreloader();
.progressbar {
width:200px;
height:50px;
margin:20px auto;
border:solid 1px grey;
}
.progressbar-inner {
width:inherit;
height:inherit;
}
.progressbar-progress {
background-color:grey;
height:inherit;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment