resources/js/jquery.preload.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
/**
* 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;
};
|