Permalink
Browse files

registering deferred methods with callback argument, fixes #30

  • Loading branch information...
1 parent 26e74ab commit c7634aa6a4468d2d04a5365c81100ef67570faaa @darsain darsain committed Sep 10, 2012
Showing with 212 additions and 135 deletions.
  1. +111 −48 README.markdown
  2. +32 −29 index.html
  3. +12 −1 jquery.imagesloaded.js
  4. +53 −53 js/main.js
  5. +4 −4 js/vendor/plugins.js
View
@@ -4,32 +4,90 @@ http://desandro.github.com/imagesloaded/
A jQuery plugin that triggers a callback after all the selected/child images have been loaded. Because you can't do `.load()` on cached images.
-## Basic usage
+
+## Calling
+
+```js
+$(selector).imagesLoaded( [ callback ] );
+```
+
+### selector
+
+ImagesLoaded can be called on an elements with images within them, images directly, or a combination of both.
+
+###### *Example*
+
+```js
+// Calling on an element that may contain images
+$('#content').imagesLoaded(fn);
+
+// Calling on image elements directly
+$('img').imagesLoaded(fn);
+
+// Combination of both
+$('#content, #gallery > img').imagesLoaded(fn);
+```
+
+### [ callback ]
+
+Callback argument can be a function, or an object map with deferred methods.
+
+#### callback:function
+
+Pass a function to be called when all images has finished with loading. This is the simplest way how to use imagesLoaded.
+
+##### *this*
+
+When executed, the callback function scope (`this`) is a jQuery object with element or set of elements on which the imagesLoaded has been called (`$(selector)`).
+
+##### arguments
+
+Callback function receives 3 arguments:
+
++ **$images:** `Object` jQuery object with all images
++ **$proper:** `Object` jQuery object with properly loaded images
++ **$broken:** `Object` jQuery object with broken images
+
+###### *Example*
+
+```js
+$('#my-container, .article img').imagesLoaded( function( $images, $proper, $broken ) {
+ console.log( $images.length + ' images total have been loaded' );
+ console.log( $proper.length + ' properly loaded images' );
+ console.log( $broken.length + ' broken images' );
+});
+```
+
+#### callback:object
+
+To bind deferred methods before the determination process starts, pass an object with map of given method callbacks instead of a callback function.
+You can read more about these methods and their behavior in [Deferred section](#deferred) below.
+
+###### *Example*
```js
-$('#my-container').imagesLoaded( function( $images, $proper, $broken ) {
- // callback provides three arguments:
- // $images: the jQuery object with all images
- // $proper: the jQuery object with properly loaded images
- // $broken: the jQuery object with broken images
- // `this` is a jQuery object of container
- console.log( $images.length + ' images total have been loaded in ' + this );
- console.log( $proper.length + ' properly loaded images' );
- console.log( $broken.length + ' broken images' );
+$(selector).imagesLoaded({
+ done: function ($images) {},
+ fail: function ($images, $proper, $broken) {},
+ always: function () {},
+ progress: function (isBroken, $images, $proper, $broken) {}
});
```
-You can call `imagesLoaded` on a set of images as well.
+If you are passing object with deferred methods, but you still want to use the simple callback functionality, use the `callback` property, like so:
```js
-$('.article img').imagesLoaded( myFunction );
+$(selector).imagesLoaded({
+ // ... deferred methods ...
+ callback: function ($images, $proper, $broken) {}
+});
```
+
## Deferred
As of v1.2.0, `imagesLoaded` returns jQuery deferred object.
-
### Behaviour
**Resolved**: deferred is *resolved* when all images have been properly loaded
@@ -40,76 +98,82 @@ As of v1.2.0, `imagesLoaded` returns jQuery deferred object.
### Usage
```js
-var dfd = $('#my-container').imagesLoaded(); // save a deferred object
+// Save a deferred object with postponed determination process
+var dfd = $('#my-container').imagesLoaded();
// Always
dfd.always( function(){
- console.log( 'all images has finished with loading, do some stuff...' );
+ console.log( 'all images has finished with loading, do some stuff...' );
});
// Resolved
dfd.done( function( $images ){
- // callback provides one argument:
- // $images: the jQuery object with all images
- console.log( 'deferred is resolved with ' + $images.length + ' properly loaded images' );
+ // callback provides one argument:
+ // $images: the jQuery object with all images
+ console.log( 'deferred is resolved with ' + $images.length + ' properly loaded images' );
});
// Rejected
dfd.fail( function( $images, $proper, $broken ){
- // callback provides three arguments:
- // $images: the jQuery object with all images
- // $proper: the jQuery object with properly loaded images
- // $broken: the jQuery object with broken images
- console.log( 'deferred is rejected with ' + $broken.length + ' out of ' + $images.length + ' images broken' );
+ // callback provides three arguments:
+ // $images: the jQuery object with all images
+ // $proper: the jQuery object with properly loaded images
+ // $broken: the jQuery object with broken images
+ console.log( 'deferred is rejected with ' + $broken.length + ' out of ' + $images.length + ' images broken' );
});
// Notified
dfd.progress( function( isBroken, $images, $proper, $broken ){
- // function scope (this) is a jQuery object with image that has just finished loading
- // callback provides four arguments:
- // isBroken: boolean value of whether the loaded image (this) is broken
- // $images: jQuery object with all images in set
- // $proper: jQuery object with properly loaded images so far
- // $broken: jQuery object with broken images so far
- console.log( 'Loading progress: ' + ( $proper.length + $broken.length ) + ' out of ' + $images.length );
+ // function scope (this) is a jQuery object with image that has just finished loading
+ // callback provides four arguments:
+ // isBroken: boolean value of whether the loaded image (this) is broken
+ // $images: jQuery object with all images in set
+ // $proper: jQuery object with properly loaded images so far
+ // $broken: jQuery object with broken images so far
+ console.log( 'Loading progress: ' + ( $proper.length + $broken.length ) + ' out of ' + $images.length );
});
```
+**Important!**: progress method should be always registered with `callback:object` argument, which ensures that it will be registered before the determination process starts.
+Otherwise you might run into an issue where by the time you register the progress method all images have been loaded, and there is nothing to report anymore.
+
### Requirements
-Deferred is being used only when present, so having older versions of jQuery doesn't break the plugin, just removes the functionality.
-For using any Deferred method, you need jQuery **v1.5** and higher.
-For using Deferred progress method, you need jQuery **v1.7** and higher.
-For availability of other Deferred methods, read the [jQuery Deferred object documentation](http://api.jquery.com/category/deferred-object/).
++ Deferred is being used only when present, so having older versions of jQuery doesn't break the plugin, just removes the functionality.
++ For using any Deferred method, you need jQuery **v1.5** and higher.
++ For using Deferred progress method, you need jQuery **v1.7** and higher.
++ For availability of other Deferred methods, read the [jQuery Deferred object documentation](http://api.jquery.com/category/deferred-object/).
## Behavior notes
+### Determination process
+
+Every browser is handling image elements differently. We are trying to check for state in image attributes when possible & reliable, but in some browsers (especially older ones)
+we have to reset `img.src` attribute to re-trigger load/error events. That is the only possible way how to check for an image status,
+as well as differentiate between proper and broken images. We are resetting the src with blank image data-uri to bypass webkit log warning (thx doug jones).
+
+Fortunately, since v2.0.0 we are in a state where imagesLoaded is both cross-browser reliable and fast, with only a few minor [known issues](#known-issues).
+
### Caching
-The state of all once checked images is cached, so the calls repeated on the same images don't have to go through a determining process for each image again.
+The state of all once checked images is cached, so the calls repeated on the same images don't have to go through a determination process for each image again.
Determining might be slow in older browsers in which we have to reset `src`, and also might introduce image flickering.
-Image state is stored in `$.data` associated to that particular image DOM element. That means that everything is stored per page load,
-so you don't have to worry that temporarily unavailable images will be considered as broken on a next page load as well. This is just for a multiple calls within one page load.
+Image state is stored in `$.data` associated to that particular image DOM element and its `src` path (changing `src` of an image resets its cache).
+That means that everything is stored per page load, so you don't have to worry that temporarily unavailable images will be considered as broken on a next page load as well.
+Caching is just for a multiple calls within one page load.
If, however, you need it from some reason, you can remove this data from an image with:
```js
$.removeData( img, 'imagesLoaded' );
```
-### Image flickering
-
-In IE (particularly in older versions) you might see images flicker as plugin has to refresh all `src` attributes to catch event types. That is the only known
-way how to check for loading status of both proper and broken images in IE browsers, as these dinosaurs don't bother changing any image property once an image has
-been recognized as broken. The only thing they do is send an `error` event. Without refreshing `src` and catching it, it would be impossible to differentiate
-between broken images and proper images that are still loading.
-
-Thankfully, this flickering is invisible most of the time.
-
## Known issues
-+ unreliable differentiation between proper and broken images in Opera versions lower than 11 (market share ~0.1%), but callback still fires
++ Unreliable differentiation between proper and broken images in Opera versions lower than 11 (market share ~0.1%), but callback still fires.
++ In IE (particularly in older versions) you might see images flicker as plugin has to refresh all `src` attributes to catch event types.
+ Thankfully, this flickering is invisible most of the time.
## Contribute
@@ -120,4 +184,3 @@ It ain't easy knowing when images have loaded. [Every browser has its own little
+ [**View contributors**](https://github.com/desandro/imagesloaded/contributors)
+ [ajp](http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f)
+ Oren Solomianik
-
View
@@ -69,17 +69,17 @@ <h2>Code</h2>
<pre><code class="language-javascript">
// Call imagesLoaded and position images
-holder.imagesLoaded(function( $images, $proper, $broken ){
+$holder.imagesLoaded(function( $images, $proper, $broken ){
- var $container = this,
- x = 1;
+ var $container = this,
+ x = 1;
- $images.each( function() {
- var $this = $(this).css({ left: x });
- x += $this.width() + 1;
- });
+ $images.each( function() {
+ var $this = $(this).css({ left: x });
+ x += $this.width() + 1;
+ });
- $container.width(x);
+ $container.width(x);
});
</code></pre>
@@ -143,37 +143,40 @@ <h2>Code</h2>
<h2>Code</h2>
<pre><code class="language-javascript">
-// Call imagesLoaded with callback and save the deferred object
-var dfd = $("#holder").imagesLoaded(function( $images, $proper, $broken ){
+// Call imagesLoaded with multiple callbacks, and save the deferred object
+var dfd = $holder.imagesLoaded({
+ callback: function($images, $proper, $broken){
- totalLabel.text( $images.length );
- properLabel.text( $proper.length );
- brokenLabel.text( $broken.length );
+ $totalLabel.text( $images.length );
+ $properLabel.text( $proper.length );
+ $brokenLabel.text( $broken.length );
-});
+ },
+ progress: function (isBroken, $images, $proper, $broken) {
-// Deferred magic
-dfd.progress(function( isBroken, $images, $proper, $broken ){
+ var loadingSpan = this.siblings('.loading');
- var loadingSpan = this.siblings('.loading');
+ if( isBroken ){
+ loadingSpan.removeClass('loading').addClass('broken');
+ } else {
+ loadingSpan.fadeOut(200, function(){ $(this).remove(); });
+ }
- if( isBroken ){
- loadingSpan.removeClass('loading').addClass('broken')
- } else {
- loadingSpan.fadeOut(200, function(){ $(this).remove(); });
- }
+ $progressBar.css({ width: Math.round( ( ( $proper.length + $broken.length ) * 100 ) / $images.length ) + '%' });
- progressBar.css({ width: Math.round( ( ( $proper.length + $broken.length ) * 100 ) / $images.length ) + '%' });
+ }
+ });
-}).always(function(){
+// Subsequent deferred method registration (not to be used with progress method)
+dfd.always(function(){
- var dfdState = dfd.state();
+ var dfdState = dfd.state();
- dfdLabel.addClass( 'label-' + ( dfdState === 'resolved' ? 'success' : 'important' ) ).text( dfdState );
+ $dfdLabel.addClass( 'label-' + ( dfdState === 'resolved' ? 'success' : 'important' ) ).text( dfdState );
- progress.hide();
- statusBar.show();
- progressBar.css({ width: 0 });
+ $progress.hide();
+ $statusBar.show();
+ $progressBar.css({ width: 0 });
});
</code></pre>
View
@@ -1,5 +1,5 @@
/*!
- * jQuery imagesLoaded plugin v2.0.1
+ * jQuery imagesLoaded plugin v2.1.0
* http://github.com/desandro/imagesloaded
*
* MIT License. by Paul Irish et al.
@@ -23,6 +23,17 @@ $.fn.imagesLoaded = function( callback ) {
proper = [],
broken = [];
+ // Register deferred callbacks
+ if ($.isPlainObject(callback)) {
+ $.each(callback, function (key, value) {
+ if (key === 'callback') {
+ callback = value;
+ } else if (deferred) {
+ deferred[key](value);
+ }
+ });
+ }
+
function doneLoading() {
var $proper = $(proper),
$broken = $(broken);
Oops, something went wrong.

0 comments on commit c7634aa

Please sign in to comment.