Browse files

Tidied code, added 'status' argument of image loading, added custom s…

…elector
  • Loading branch information...
1 parent e3906fe commit 8f370ea5e7d615904ff3f5e539a5e7d966d49b3e @alexanderdickson committed Sep 5, 2011
Showing with 97 additions and 66 deletions.
  1. +3 −0 .gitignore
  2. +16 −8 README.md
  3. +40 −38 examples/callback-each.html
  4. +38 −20 jquery.waitforimages.js
View
3 .gitignore
@@ -0,0 +1,3 @@
+# Ignore testing files.
+
+examples/*
View
24 README.md
@@ -1,4 +1,4 @@
-#waitForImages 1.2.2#
+#waitForImages 1.3#
Copyright (c) 2011 Alex Dickson
@@ -8,12 +8,15 @@ Licensed under the MIT licenses.
##Overview##
-Provides usefull callbacks once descendent images have loaded.
+Provides useful callbacks once descendent images have loaded.
-waitForImages 1.2 now supports images references in CSS.
+waitForImages also supports images references in CSS.
-It can be useful when WebKit incorrectly reports element dimensions on document ready, because it has not calculated their descendent img dimensions yet.
+It can be useful when WebKit incorrectly reports element dimensions/offsets on document ready, because it has not calculated their descendent `img` dimensions yet.
+##Thanks##
+
+Matt Scharley.

Aww shucks, a 4 line patch and I get a mention? Thanks for a great plugin, it worked a treat for us :)

@alexanderdickson
Owner

Thanks for taking the time to fix my blunders :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
##Usage##
@@ -33,17 +36,20 @@ You can pass a second function as a callback. It will be called for each image t
$('selector').waitForImages(function() {
- alert('All images are loaded.');
+ alert('All images have loaded.');
- }, function(loaded, count) {
+ }, function(loaded, count, success) {
- alert(loaded + ' of ' + count + ' images have loaded.');
+ alert(loaded + ' of ' + count + ' images has ' + (success ? 'failed to load' : 'loaded') + '.');
$(this).addClass('loaded');
});
+
You can also set the third argument to true if you'd like the plugin to iterate over all elements, checking for images referenced in the CSS. If it finds any, they will be treated as an image and loaded.
+The callback will be called on the successful **and** unsuccessful loading of the image. Check the third argument to determine the success of the image load. It will be `true` if the image loaded successfully.
+
Alternatively, you can pass an object literal to the plugin, instead of the arguments individually.
$('selector').waitForImages({
@@ -58,4 +64,6 @@ Alternatively, you can pass an object literal to the plugin, instead of the argu
You may also set the CSS properties that possibly contain image references yourself. Just assign an array of properties to the plugin.
- $.fn.waitForImages.hasImgProperties = ['backgroundImage'];
+ $.waitForImages.hasImgProperties = ['backgroundImage'];
+
+waitForImages also exposes a custom selector, `:uncached`, which when used in conjunction with the `img` selector, allows you to select `img` elements that are not cached already by the browser.
View
78 examples/callback-each.html
@@ -1,44 +1,46 @@
<!DOCTYPE html>
<html>
<head>
- <meta http-equiv="content-type" content="text/html; charset=UTF-8">
- <title>waitForImages test</title>
-
-
- <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
- <script type="text/javascript" src="../jquery.waitforimages.js"></script>
-
- <script type="text/javascript">
- //<![CDATA
-
- $(function() {
-
- // Make a bunch of images that our browser has to download for this example.
- for (var j = 0; j < 20; j++) {
-
- $('<img />', {
- 'alt': '',
- 'src': 'http://www.gravatar.com/avatar/' + Math.ceil(Math.random() * 32) + '?s=100&d=identicon',
- 'width': '10px',
- 'height': '10px'
- }).appendTo('body');
-
- }
-
- // Test plugin
-
- $('body').waitForImages(
- function() {
- $('body').append('<p>Images loaded.</p>');
- },
- function(loaded, total) {
- $(this).css({ border: '1px solid #ccc' });
- $('body').append('<p>Image ' + loaded + ' of ' + total + ' loaded.</p>');
- });
-
- });
- //]]>
- </script>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+ <title>waitForImages test</title>
+
+
+ <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js"></script>
+ <script type="text/javascript" src="../jquery.waitforimages.js"></script>
+
+ <script type="text/javascript">
+ //<![CDATA
+
+ $(function() {
+
+ // Make a bunch of images that our browser has to download for this example.
+ for (var j = 0; j < 20; j++) {
+
+ $('<div />', {
+ css: {'backgroundImage': 'url("http://www.gravatar.com/avatar/' + Math.ceil(Math.random() * 32) + '?s=10&d=identicon")',
+ 'width': '10px',
+ 'height': '10px'
+ }
+ }).appendTo('body');
+
+ }
+
+ //return;
+
+ // Test plugin
+ $.waitForImages.hasImageProperties = ['bh'];
+ $('body').waitForImages(
+ function() {
+ $('body').append('<p>Images loaded.</p>');
+ },
+ function(loaded, total) {
+ $(this).css({ border: '1px solid #ccc' });
+ $('body').append('<p>Image ' + loaded + ' of ' + total + ' loaded.</p>');
+ }, true);
+
+ });
+ //]]>
+ </script>
</head>
<body>
View
58 jquery.waitforimages.js
@@ -1,5 +1,5 @@
/*
- * waitForImages 1.2.2
+ * waitForImages 1.3
* -----------------
* Provides a callback when all images have loaded in your given selector.
* http://www.alexanderdickson.com/
@@ -12,10 +12,27 @@
*/
;(function($) {
+
+ // CSS properties which contain references to images.
+ $.waitForImages = {
+ hasImageProperties: [
+ 'backgroundImage',
+ 'listStyleImage',
+ 'borderImage',
+ 'borderCornerImage'
+ ]
+ };
+
+ // Custom selector to find `img` elements that have a valid `src` attribute and have not already loaded.
+ $.expr[':'].uncached = function(obj) {
+ return $(obj).is('img[src!=""]') && ! obj.complete;
+ };
+
$.fn.waitForImages = function(finishedCallback, eachCallback, waitForAll) {
// Handle options object.
- if (typeof finishedCallback === 'object') {
+ // Use this convoluted form because `typeof` says an `Array` is an `Object`.
+ if (Object.prototype.toString.call(finishedCallback) == '[object Object]') {
eachCallback = finishedCallback.each;
waitForAll = finishedCallback.waitForAll;
finishedCallback = finishedCallback.finished;
@@ -40,21 +57,15 @@
if (waitForAll) {
// CSS properties which may contain an image.
- var hasImgProperties = $.fn.waitForImages.hasImgProperties || [
- 'backgroundImage',
- 'listStyleImage',
- 'borderImage',
- 'borderCornerImage'
- ];
-
- var matchUrl = /url\((['"]?)(.*?)\1\)/g;
-
+ var hasImgProperties = $.waitForImages.hasImageProperties,
+ matchUrl = /url\((['"]?)(.*?)\1\)/g;
+
// Get all elements, as any one of them could have a background image.
- obj.find('*').filter(function() {
+ obj.find('*').each(function() {
var element = $(this);
// If an `img` element, add it. But keep iterating in case it has a background image too.
- if (element.is('img[src!=""]')) {
+ if (element.is('img:uncached')) {
allImgs.push({
src: element.attr('src'),
element: element[0]
@@ -80,7 +91,9 @@
});
} else {
// For images only, the task is simpler.
- obj.find('img[src!=""]').each(function() {
+ obj
+ .find('img:uncached')
+ .each(function() {
allImgs.push({
src: this.src,
element: this
@@ -97,20 +110,25 @@
};
$.each(allImgs, function(i, img) {
-
+
var image = new Image;
-
- image.onload = function() {
+
+ // Handle the image loading and error with the same callback.
+ $(image).bind('load error', function(event) {
allImgsLoaded++;
- eachCallback.call(img.element, allImgsLoaded, allImgsLength);
+
+ // If an error occurred with loading the image, set the third argument accordingly.
+ eachCallback.call(img.element, allImgsLoaded, allImgsLength, event.type == 'load');
+
if (allImgsLoaded == allImgsLength) {
finishedCallback.call(obj[0]);
return false;
};
- };
+
+ });
image.src = img.src;
});
});
};
-})(jQuery);
+})(jQuery);

0 comments on commit 8f370ea

Please sign in to comment.