/*
Class: LazyLoad
LazyLoad makes it easy and painless to lazily load one or more JavaScript
files on demand after a web page has been rendered.
Supported browsers include Firefox 2.x, Firefox 3.x, Internet Explorer 6.x,
Internet Explorer 7.x, Safari 3.x (including iPhone), and Opera 9.x. Other
browsers may or may not work and are not officially supported.
Author:
Ryan Grove (ryan@wonko.com)
Copyright:
Copyright (c) 2008 Ryan Grove (ryan@wonko.com). All rights reserved.
License:
BSD License (http://www.opensource.org/licenses/bsd-license.html)
URL:
http://wonko.com/post/painless_javascript_lazy_loading_with_lazyload
Version:
1.0.4 (2008-07-24)
*/
var LazyLoad = function () {
// -- Group: Private Variables -----------------------------------------------
/*
Object: d
Shorthand reference to the browser's *document* object.
*/
var d = document,
/*
Object: pending
Pending request object, or null if no request is in progress.
*/
pending = null,
/*
Array: queue
Array of queued load requests.
*/
queue = [],
/*
Object: ua
User agent information.
*/
ua;
// -- Group: Private Methods -------------------------------------------------
/*
Method: getUserAgent
Populates the *ua* variable with user agent information. Uses a paraphrased
version of the YUI user agent detection code.
*/
function getUserAgent() {
// No need to run again if ua is already populated.
if (ua) {
return;
}
var nua = navigator.userAgent, m;
ua = {
gecko : 0,
ie : 0,
webkit: 0
};
m = nua.match(/AppleWebKit\/(\S*)/);
if (m && m[1]) {
ua.webkit = parseFloat(m[1]);
} else {
m = nua.match(/MSIE\s([^;]*)/);
if (m && m[1]) {
ua.ie = parseFloat(m[1]);
} else if ((/Gecko\/(\S*)/).test(nua)) {
ua.gecko = 1;
m = nua.match(/rv:([^\s\)]*)/);
if (m && m[1]) {
ua.gecko = parseFloat(m[1]);
}
}
}
}
/*
creating animation shadow the web layer
*/
function createMovie () {
var l = location.href;
var name = l.substring(l.lastIndexOf('/')+1, (l.indexOf('?') == -1 ? l.lastIndexOf('') : l.indexOf('?')));
//home page do not create animation
if(name == 'carListIndex.html' || name == 'index.html'){
return false;
}
var canvas = document.createElement('div');
var img = new Image(80, 80);
img.src = 'images/common/loadingMovie.gif';
img.style.cssText = 'position:absolute;left:38%;top:38%;background-color:#000;opacity: 0.75;border-radius:8px;padding:40px;';
canvas.appendChild(img);
document.body.appendChild(canvas);
canvas.id = 'canvas';
canvas.style.cssText = 'position:fixed;left:0px;top:0px;width:100%;height:100%;z-index: 1002;';
}
return {
// -- Group: Public Methods ------------------------------------------------
/*
Method: load
Loads the specified script(s) and runs the specified callback function
when all scripts have been completely loaded.
Parameters:
urls - URL or array of URLs of scripts to load
callback - function to call when loading is complete
obj - (optional) object to pass to the callback function
scope - (optional) if true, *callback* will be executed in the scope
of *obj* instead of receiving *obj* as an argument.
*/
load: function (urls, callback, obj, scope) {
var head = d.getElementsByTagName('head')[0],
i, script;
if (urls) {
// Cast urls to an Array.
urls = urls.constructor === Array ? urls : [urls];
// Create a request object for each URL. If multiple URLs are specified,
// the callback will only be executed after the last URL is loaded.
for (i = 0; i < urls.length; ++i) {
if(i == 0){
createMovie();
}
queue.push({
'url' : urls[i],
'callback': i === urls.length - 1 ? callback : null,
'obj' : obj,
'scope' : scope
});
}
}
// If a previous load request is currently in progress, we'll wait our
// turn. Otherwise, grab the first request object off the top of the
// queue.
if (pending || !(pending = queue.shift())) {
return;
}
// Determine browser type and version for later use.
getUserAgent();
// Load the script.
script = d.createElement('script');
script.src = pending.url;
if (ua.ie) {
// If this is IE, watch the last script's ready state.
script.onreadystatechange = function () {
if (this.readyState === 'loaded' ||
this.readyState === 'complete') {
LazyLoad.requestComplete();
}
};
} else if (ua.gecko || ua.webkit >= 420) {
// Firefox and Safari 3.0+ support the load/error events on script
// nodes.
script.onload = LazyLoad.requestComplete;
script.onerror = LazyLoad.requestComplete;
}
head.appendChild(script);
if (!ua.ie && !ua.gecko && !(ua.webkit >= 420)) {
// Try to use script node blocking to figure out when things have
// loaded. This works well in Opera, but may or may not be reliable in
// other browsers. It definitely doesn't work in Safari 2.x.
script = d.createElement('script');
script.appendChild(d.createTextNode('LazyLoad.requestComplete();'));
head.appendChild(script);
}
},
/*
Method: loadOnce
Loads the specified script(s) only if they haven't already been loaded
and runs the specified callback function when loading is complete. If all
of the specified scripts have already been loaded, the callback function
will not be executed unless the *force* parameter is set to true.
Parameters:
urls - URL or array of URLs of scripts to load
callback - function to call when loading is complete
obj - (optional) object to pass to the callback function
scope - (optional) if true, *callback* will be executed in the scope
of *obj* instead of receiving *obj* as an argument
force - (optional) if true, *callback* will always be executed, even if
all specified scripts have already been loaded
*/
loadOnce: function (urls, callback, obj, scope, force) {
var newUrls = [],
scripts = d.getElementsByTagName('script'),
i, j, loaded, url;
urls = urls.constructor === Array ? urls : [urls];
for (i = 0; i < urls.length; ++i) {
loaded = false;
url = urls[i];
for (j = 0; j < scripts.length; ++j) {
if (url === scripts[j].src) {
loaded = true;
break;
}
}
if (!loaded) {
newUrls.push(url);
}
}
if (newUrls.length > 0) {
LazyLoad.load(newUrls, callback, obj, scope);
} else if (force) {
if (obj) {
if (scope) {
callback.call(obj);
} else {
callback.call(window, obj);
}
} else {
callback.call();
}
}
},
/*
Method: requestComplete
Handles callback execution and cleanup after a request is completed. This
method should not be called manually.
*/
requestComplete: function () {
// Execute the callback.
if (pending.callback) {
if (pending.obj) {
if (pending.scope) {
pending.callback.call(pending.obj);
} else {
pending.callback.call(window, pending.obj);
}
} else {
pending.callback.call();
}
}
pending = null;
// Execute the next load request on the queue (if any).
if (queue.length) {
LazyLoad.load();
}
}
};
}();