1/* 2 * waitForImages 1.4 3 * ----------------- 4 * Provides a callback when all images have loaded in your given selector. 5 * http://www.alexanderdickson.com/ 6 * 7 * 8 * Copyright (c) 2011 Alex Dickson 9 * Licensed under the MIT licenses. 10 * See website for more info. 11 * 12 */ 13 14;(function($) { 15 // Namespace all events. 16 var eventNamespace = 'waitForImages'; 17 18 // CSS properties which contain references to images. 19 $.waitForImages = { 20 hasImageProperties: [ 21 'backgroundImage', 22 'listStyleImage', 23 'borderImage', 24 'borderCornerImage' 25 ] 26 }; 27 28 // Custom selector to find `img` elements that have a valid `src` attribute and have not already loaded. 29 $.expr[':'].uncached = function(obj) { 30 // Ensure we are dealing with an `img` element with a valid `src` attribute. 31 if ( ! $(obj).is('img[src!=""]')) { 32 return false; 33 } 34 35 // Firefox's `complete` property will always be`true` even if the image has not been downloaded. 36 // Doing it this way works in Firefox. 37 var img = document.createElement('img'); 38 img.src = obj.src; 39 return ! img.complete; 40 }; 41 42 $.fn.waitForImages = function(finishedCallback, eachCallback, waitForAll) { 43 44 // Handle options object. 45 if ($.isPlainObject(arguments[0])) { 46 eachCallback = finishedCallback.each; 47 waitForAll = finishedCallback.waitForAll; 48 finishedCallback = finishedCallback.finished; 49 } 50 51 // Handle missing callbacks. 52 finishedCallback = finishedCallback || $.noop; 53 eachCallback = eachCallback || $.noop; 54 55 // Convert waitForAll to Boolean 56 waitForAll = !! waitForAll; 57 58 // Ensure callbacks are functions. 59 if (!$.isFunction(finishedCallback) || !$.isFunction(eachCallback)) { 60 throw new TypeError('An invalid callback was supplied.'); 61 }; 62 63 return this.each(function() { 64 // Build a list of all imgs, dependent on what images will be considered. 65 var obj = $(this), 66 allImgs = []; 67 68 if (waitForAll) { 69 // CSS properties which may contain an image. 70 var hasImgProperties = $.waitForImages.hasImageProperties || [], 71 matchUrl = /url\((['"]?)(.*?)\1\)/g; 72 73 // Get all elements, as any one of them could have a background image. 74 obj.find('*').each(function() { 75 var element = $(this); 76 77 // If an `img` element, add it. But keep iterating in case it has a background image too. 78 if (element.is('img:uncached')) { 79 allImgs.push({ 80 src: element.attr('src'), 81 element: element[0] 82 }); 83 } 84 85 $.each(hasImgProperties, function(i, property) { 86 var propertyValue = element.css(property); 87 // If it doesn't contain this property, skip. 88 if ( ! propertyValue) { 89 return true; 90 } 91 92 // Get all url() of this element. 93 var match; 94 while (match = matchUrl.exec(propertyValue)) { 95 allImgs.push({ 96 src: match[2], 97 element: element[0] 98 }); 99 }; 100 }); 101 }); 102 } else { 103 // For images only, the task is simpler. 104 obj 105 .find('img:uncached') 106 .each(function() { 107 allImgs.push({ 108 src: this.src, 109 element: this 110 }); 111 }); 112 }; 113 114 var allImgsLength = allImgs.length, 115 allImgsLoaded = 0; 116 117 // If no images found, don't bother. 118 if (allImgsLength == 0) { 119 finishedCallback.call(obj[0]); 120 }; 121 122 $.each(allImgs, function(i, img) { 123 124 var image = new Image; 125 126 // Handle the image loading and error with the same callback. 127 $(image).bind('load.' + eventNamespace + ' error.' + eventNamespace, function(event) { 128 allImgsLoaded++; 129 130 // If an error occurred with loading the image, set the third argument accordingly. 131 eachCallback.call(img.element, allImgsLoaded, allImgsLength, event.type == 'load'); 132 133 if (allImgsLoaded == allImgsLength) { 134 finishedCallback.call(obj[0]); 135 return false;
136 }; 137 138 }); 139 140 image.src = img.src; 141 }); 142 }); 143 }; 144})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.