146 lines
7.0 KiB
JavaScript
146 lines
7.0 KiB
JavaScript
/**
|
|
* jQuery-Plugin "preloadCssImages"
|
|
* by Scott Jehl, scott@filamentgroup.com
|
|
* http://www.filamentgroup.com
|
|
* reference article: http://www.filamentgroup.com/lab/update_automatically_preload_images_from_css_with_jquery/
|
|
* demo page: http://www.filamentgroup.com/examples/preloadImages/index_v2.php
|
|
*
|
|
* Copyright (c) 2008 Filament Group, Inc
|
|
* Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses.
|
|
*
|
|
* Version: 5.0, 10.31.2008
|
|
* Changelog:
|
|
* 02.20.2008 initial Version 1.0
|
|
* 06.04.2008 Version 2.0 : removed need for any passed arguments. Images load from any and all directories.
|
|
* 06.21.2008 Version 3.0 : Added options for loading status. Fixed IE abs image path bug (thanks Sam Pohlenz).
|
|
* 07.24.2008 Version 4.0 : Added support for @imported CSS (credit: http://marcarea.com/). Fixed support in Opera as well.
|
|
* 10.31.2008 Version: 5.0 : Many feature and performance enhancements from trixta
|
|
* --------------------------------------------------------------------
|
|
*/
|
|
;
|
|
jQuery.preloadCssImages = function (settings) {
|
|
settings = jQuery.extend({
|
|
statusTextEl: null,
|
|
statusBarEl: null,
|
|
errorDelay: 999,
|
|
// handles 404-Errors in IE
|
|
simultaneousCacheLoading: 2
|
|
}, settings);
|
|
var allImgs = [],
|
|
loaded = 0,
|
|
imgUrls = [],
|
|
thisSheetRules, errorTimer;
|
|
|
|
function onImgComplete() {
|
|
clearTimeout(errorTimer);
|
|
if (imgUrls && imgUrls.length && imgUrls[loaded]) {
|
|
loaded++;
|
|
if (settings.statusTextEl) {
|
|
var nowloading = (imgUrls[loaded]) ? 'Now Loading: <span>' + imgUrls[loaded].split('/')[imgUrls[loaded].split('/').length - 1] : 'Loading complete'; // wrong status-text bug fixed
|
|
jQuery(settings.statusTextEl).html('<span class="numLoaded">' + loaded + '</span> of <span class="numTotal">' + imgUrls.length + '</span> loaded (<span class="percentLoaded">' + (loaded / imgUrls.length * 100).toFixed(0) + '%</span>) <span class="currentImg">' + nowloading + '</span></span>');
|
|
}
|
|
if (settings.statusBarEl) {
|
|
var barWidth = jQuery(settings.statusBarEl).width();
|
|
jQuery(settings.statusBarEl).css('background-position', -(barWidth - (barWidth * loaded / imgUrls.length).toFixed(0)) + 'px 50%');
|
|
}
|
|
loadImgs();
|
|
}
|
|
}
|
|
|
|
function loadImgs() {
|
|
//only load 1 image at the same time / most browsers can only handle 2 http requests, 1 should remain for user-interaction (Ajax, other images, normal page requests...)
|
|
// otherwise set simultaneousCacheLoading to a higher number for simultaneous downloads
|
|
if (imgUrls && imgUrls.length && imgUrls[loaded]) {
|
|
var img = new Image(); //new img obj
|
|
img.src = imgUrls[loaded]; //set src either absolute or rel to css dir
|
|
if (!img.complete) {
|
|
jQuery(img).bind('error load onreadystatechange', onImgComplete);
|
|
} else {
|
|
onImgComplete();
|
|
}
|
|
errorTimer = setTimeout(onImgComplete, settings.errorDelay); // handles 404-Errors in IE
|
|
}
|
|
}
|
|
|
|
function parseCSS(sheets, urls) {
|
|
var w3cImport = false,
|
|
imported = [],
|
|
importedSrc = [],
|
|
baseURL;
|
|
var sheetIndex = sheets.length;
|
|
while (sheetIndex--) { //loop through each stylesheet
|
|
var cssPile = ''; //create large string of all css rules in sheet
|
|
if (urls && urls[sheetIndex]) {
|
|
baseURL = urls[sheetIndex];
|
|
} else {
|
|
var csshref = (sheets[sheetIndex].href) ? sheets[sheetIndex].href : 'window.location.href';
|
|
var baseURLarr = csshref.split('/'); //split href at / to make array
|
|
baseURLarr.pop(); //remove file path from baseURL array
|
|
baseURL = baseURLarr.join('/'); //create base url for the images in this sheet (css file's dir)
|
|
if (baseURL) {
|
|
baseURL += '/'; //tack on a / if needed
|
|
}
|
|
}
|
|
if (sheets[sheetIndex].cssRules || sheets[sheetIndex].rules) {
|
|
thisSheetRules = (sheets[sheetIndex].cssRules) ? //->>> http://www.quirksmode.org/dom/w3c_css.html
|
|
sheets[sheetIndex].cssRules : //w3
|
|
sheets[sheetIndex].rules; //ie
|
|
var ruleIndex = thisSheetRules.length;
|
|
while (ruleIndex--) {
|
|
if (thisSheetRules[ruleIndex].style && thisSheetRules[ruleIndex].style.cssText) {
|
|
var text = thisSheetRules[ruleIndex].style.cssText;
|
|
if (text.toLowerCase().indexOf('url') != -1) { // only add rules to the string if you can assume, to find an image, speed improvement
|
|
cssPile += text; // thisSheetRules[ruleIndex].style.cssText instead of thisSheetRules[ruleIndex].cssText is a huge speed improvement
|
|
}
|
|
} else if (thisSheetRules[ruleIndex].styleSheet) {
|
|
imported.push(thisSheetRules[ruleIndex].styleSheet);
|
|
w3cImport = true;
|
|
}
|
|
|
|
}
|
|
}
|
|
//parse cssPile for image urls
|
|
var tmpImage = cssPile.match(/[^\("]+\.(gif|jpg|jpeg|png)/g); //reg ex to get a string of between a "(" and a ".filename" / '"' for opera-bugfix
|
|
if (tmpImage) {
|
|
var i = tmpImage.length;
|
|
while (i--) { // handle baseUrl here for multiple stylesheets in different folders bug
|
|
var imgSrc = (tmpImage[i].charAt(0) == '/' || tmpImage[i].match('://')) ? // protocol-bug fixed
|
|
tmpImage[i] : baseURL + tmpImage[i];
|
|
|
|
if (jQuery.inArray(imgSrc, imgUrls) == -1) {
|
|
imgUrls.push(imgSrc);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!w3cImport && sheets[sheetIndex].imports && sheets[sheetIndex].imports.length) {
|
|
for (var iImport = 0, importLen = sheets[sheetIndex].imports.length; iImport < importLen; iImport++) {
|
|
var iHref = sheets[sheetIndex].imports[iImport].href;
|
|
iHref = iHref.split('/');
|
|
iHref.pop();
|
|
iHref = iHref.join('/');
|
|
if (iHref) {
|
|
iHref += '/'; //tack on a / if needed
|
|
}
|
|
var iSrc = (iHref.charAt(0) == '/' || iHref.match('://')) ? // protocol-bug fixed
|
|
iHref : baseURL + iHref;
|
|
|
|
importedSrc.push(iSrc);
|
|
imported.push(sheets[sheetIndex].imports[iImport]);
|
|
}
|
|
|
|
|
|
}
|
|
} //loop
|
|
if (imported.length) {
|
|
parseCSS(imported, importedSrc);
|
|
return false;
|
|
}
|
|
var downloads = settings.simultaneousCacheLoading;
|
|
while (downloads--) {
|
|
setTimeout(loadImgs, downloads);
|
|
}
|
|
}
|
|
parseCSS(document.styleSheets);
|
|
return imgUrls;
|
|
}; |