preloadCssImages.jQuery_v5.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /**
  2. * jQuery-Plugin "preloadCssImages"
  3. * by Scott Jehl, scott@filamentgroup.com
  4. * http://www.filamentgroup.com
  5. * reference article: http://www.filamentgroup.com/lab/update_automatically_preload_images_from_css_with_jquery/
  6. * demo page: http://www.filamentgroup.com/examples/preloadImages/index_v2.php
  7. *
  8. * Copyright (c) 2008 Filament Group, Inc
  9. * Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses.
  10. *
  11. * Version: 5.0, 10.31.2008
  12. * Changelog:
  13. * 02.20.2008 initial Version 1.0
  14. * 06.04.2008 Version 2.0 : removed need for any passed arguments. Images load from any and all directories.
  15. * 06.21.2008 Version 3.0 : Added options for loading status. Fixed IE abs image path bug (thanks Sam Pohlenz).
  16. * 07.24.2008 Version 4.0 : Added support for @imported CSS (credit: http://marcarea.com/). Fixed support in Opera as well.
  17. * 10.31.2008 Version: 5.0 : Many feature and performance enhancements from trixta
  18. * --------------------------------------------------------------------
  19. */
  20. ;jQuery.preloadCssImages = function(settings){
  21. settings = jQuery.extend({
  22. statusTextEl: null,
  23. statusBarEl: null,
  24. errorDelay: 999, // handles 404-Errors in IE
  25. simultaneousCacheLoading: 2
  26. }, settings);
  27. var allImgs = [],
  28. loaded = 0,
  29. imgUrls = [],
  30. thisSheetRules,
  31. errorTimer;
  32. function onImgComplete(){
  33. clearTimeout(errorTimer);
  34. if (imgUrls && imgUrls.length && imgUrls[loaded]) {
  35. loaded++;
  36. if (settings.statusTextEl) {
  37. var nowloading = (imgUrls[loaded]) ?
  38. 'Now Loading: <span>' + imgUrls[loaded].split('/')[imgUrls[loaded].split('/').length - 1] :
  39. 'Loading complete'; // wrong status-text bug fixed
  40. 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>');
  41. }
  42. if (settings.statusBarEl) {
  43. var barWidth = jQuery(settings.statusBarEl).width();
  44. jQuery(settings.statusBarEl).css('background-position', -(barWidth - (barWidth * loaded / imgUrls.length).toFixed(0)) + 'px 50%');
  45. }
  46. loadImgs();
  47. }
  48. }
  49. function loadImgs(){
  50. //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...)
  51. // otherwise set simultaneousCacheLoading to a higher number for simultaneous downloads
  52. if(imgUrls && imgUrls.length && imgUrls[loaded]){
  53. var img = new Image(); //new img obj
  54. img.src = imgUrls[loaded]; //set src either absolute or rel to css dir
  55. if(!img.complete){
  56. jQuery(img).bind('error load onreadystatechange', onImgComplete);
  57. } else {
  58. onImgComplete();
  59. }
  60. errorTimer = setTimeout(onImgComplete, settings.errorDelay); // handles 404-Errors in IE
  61. }
  62. }
  63. function parseCSS(sheets, urls) {
  64. var w3cImport = false,
  65. imported = [],
  66. importedSrc = [],
  67. baseURL;
  68. var sheetIndex = sheets.length;
  69. while(sheetIndex--){//loop through each stylesheet
  70. var cssPile = '';//create large string of all css rules in sheet
  71. if(urls && urls[sheetIndex]){
  72. baseURL = urls[sheetIndex];
  73. } else {
  74. var csshref = (sheets[sheetIndex].href) ? sheets[sheetIndex].href : 'window.location.href';
  75. var baseURLarr = csshref.split('/');//split href at / to make array
  76. baseURLarr.pop();//remove file path from baseURL array
  77. baseURL = baseURLarr.join('/');//create base url for the images in this sheet (css file's dir)
  78. if (baseURL) {
  79. baseURL += '/'; //tack on a / if needed
  80. }
  81. }
  82. if(sheets[sheetIndex].cssRules || sheets[sheetIndex].rules){
  83. thisSheetRules = (sheets[sheetIndex].cssRules) ? //->>> http://www.quirksmode.org/dom/w3c_css.html
  84. sheets[sheetIndex].cssRules : //w3
  85. sheets[sheetIndex].rules; //ie
  86. var ruleIndex = thisSheetRules.length;
  87. while(ruleIndex--){
  88. if(thisSheetRules[ruleIndex].style && thisSheetRules[ruleIndex].style.cssText){
  89. var text = thisSheetRules[ruleIndex].style.cssText;
  90. if(text.toLowerCase().indexOf('url') != -1){ // only add rules to the string if you can assume, to find an image, speed improvement
  91. cssPile += text; // thisSheetRules[ruleIndex].style.cssText instead of thisSheetRules[ruleIndex].cssText is a huge speed improvement
  92. }
  93. } else if(thisSheetRules[ruleIndex].styleSheet) {
  94. imported.push(thisSheetRules[ruleIndex].styleSheet);
  95. w3cImport = true;
  96. }
  97. }
  98. }
  99. //parse cssPile for image urls
  100. var tmpImage = cssPile.match(/[^\("]+\.(gif|jpg|jpeg|png)/g);//reg ex to get a string of between a "(" and a ".filename" / '"' for opera-bugfix
  101. if(tmpImage){
  102. var i = tmpImage.length;
  103. while(i--){ // handle baseUrl here for multiple stylesheets in different folders bug
  104. var imgSrc = (tmpImage[i].charAt(0) == '/' || tmpImage[i].match('://')) ? // protocol-bug fixed
  105. tmpImage[i] :
  106. baseURL + tmpImage[i];
  107. if(jQuery.inArray(imgSrc, imgUrls) == -1){
  108. imgUrls.push(imgSrc);
  109. }
  110. }
  111. }
  112. if(!w3cImport && sheets[sheetIndex].imports && sheets[sheetIndex].imports.length) {
  113. for(var iImport = 0, importLen = sheets[sheetIndex].imports.length; iImport < importLen; iImport++){
  114. var iHref = sheets[sheetIndex].imports[iImport].href;
  115. iHref = iHref.split('/');
  116. iHref.pop();
  117. iHref = iHref.join('/');
  118. if (iHref) {
  119. iHref += '/'; //tack on a / if needed
  120. }
  121. var iSrc = (iHref.charAt(0) == '/' || iHref.match('://')) ? // protocol-bug fixed
  122. iHref :
  123. baseURL + iHref;
  124. importedSrc.push(iSrc);
  125. imported.push(sheets[sheetIndex].imports[iImport]);
  126. }
  127. }
  128. }//loop
  129. if(imported.length){
  130. parseCSS(imported, importedSrc);
  131. return false;
  132. }
  133. var downloads = settings.simultaneousCacheLoading;
  134. while( downloads--){
  135. setTimeout(loadImgs, downloads);
  136. }
  137. }
  138. parseCSS(document.styleSheets);
  139. return imgUrls;
  140. };