diff options
-rw-r--r-- | imagesloaded.js | 126 | ||||
-rw-r--r-- | sandbox/background/css/background.css | 29 | ||||
-rw-r--r-- | sandbox/background/index.html | 52 |
3 files changed, 179 insertions, 28 deletions
diff --git a/imagesloaded.js b/imagesloaded.js index 58bf2bf..0fb802a 100644 --- a/imagesloaded.js +++ b/imagesloaded.js @@ -143,6 +143,11 @@ function makeArray( obj ) { if ( elem.nodeName == 'IMG' ) { this.addImage( elem ); } + // + if ( this.options.background === true ) { + this.addElementBackgroundImages( elem ); + } + // find children // no non-element nodes, #143 var nodeType = elem.nodeType; @@ -163,6 +168,30 @@ function makeArray( obj ) { 11: true }; + ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) { + var style = getStyle( elem ); + // get `url("http://example.com/foo.jpg")`, possible multiples + var multiMatches = style.backgroundImage.match( /url\(['"]*[^'"\)]+['"]*\)/gi ); + if ( !multiMatches || !multiMatches.length ) { + return; + } + var urls = []; + for ( var i=0; i < multiMatches.length; i++ ) { + var multiMatch = multiMatches[i]; + // get `http://example.com/foo.jpg` + var urlMatches = multiMatch.match( /url\(['"]*([^'"\)]+)['"]*\)/i ); + var url = urlMatches && urlMatches[1]; + if ( url ) { + this.addBackground( url, elem ); + } + } + }; + + // IE8 + var getStyle = window.getComputedStyle || function( elem ) { + return elem.currentStyle; + }; + /** * @param {Image} img */ @@ -171,47 +200,52 @@ function makeArray( obj ) { this.images.push( loadingImage ); }; + ImagesLoaded.prototype.addBackground = function( url, elem ) { + var background = new Background( url, elem ); + this.images.push( background ); + }; + ImagesLoaded.prototype.check = function() { var _this = this; - var checkedCount = 0; - var length = this.images.length; + this.progressedCount = 0; this.hasAnyBroken = false; // complete if no images - if ( !length ) { + if ( !this.images.length ) { this.complete(); return; } - function onConfirm( image, message ) { - if ( _this.options.debug && console ) { - console.log( 'confirm', image, message ); - } - - _this.progress( image ); - checkedCount++; - if ( checkedCount == length ) { - _this.complete(); - } - return true; // bind once + function onProgress( image, elem, message ) { + _this.progress( image, elem, message ); } - for ( var i=0; i < length; i++ ) { + for ( var i=0; i < this.images.length; i++ ) { var loadingImage = this.images[i]; - loadingImage.on( 'confirm', onConfirm ); + loadingImage.once( 'progress', onProgress ); loadingImage.check(); } }; - ImagesLoaded.prototype.progress = function( image ) { + ImagesLoaded.prototype.progress = function( image, elem, message ) { + this.progressedCount++; + this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded; // HACK - Chrome triggers event before object properties have changed. #83 var _this = this; setTimeout( function() { - _this.emit( 'progress', _this, image ); + _this.emit( 'progress', _this, image, elem ); if ( _this.jqDeferred && _this.jqDeferred.notify ) { _this.jqDeferred.notify( _this, image ); } + // check if completed + if ( _this.progressedCount == _this.images.length ) { + _this.complete(); + } }); + + if ( this.options.debug && console ) { + console.log( 'progress: ' + message, image, elem ); + } }; ImagesLoaded.prototype.complete = function() { @@ -219,14 +253,12 @@ function makeArray( obj ) { this.isComplete = true; var _this = this; // HACK - another setTimeout so that confirm happens after progress - setTimeout( function() { - _this.emit( eventName, _this ); - _this.emit( 'always', _this ); - if ( _this.jqDeferred ) { - var jqMethod = _this.hasAnyBroken ? 'reject' : 'resolve'; - _this.jqDeferred[ jqMethod ]( _this ); - } - }); + _this.emit( eventName, _this ); + _this.emit( 'always', _this ); + if ( _this.jqDeferred ) { + var jqMethod = _this.hasAnyBroken ? 'reject' : 'resolve'; + _this.jqDeferred[ jqMethod ]( _this ); + } }; // -------------------------- -------------------------- // @@ -240,7 +272,8 @@ function makeArray( obj ) { LoadingImage.prototype.check = function() { // If complete is true and browser supports natural sizes, // try to check for image status manually. - if ( this.img.complete && this.img.naturalWidth !== undefined ) { + var isComplete = this.getIsImageComplete(); + if ( isComplete ) { // report based on naturalWidth this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); return; @@ -256,9 +289,13 @@ function makeArray( obj ) { this.proxyImage.src = this.img.src; }; + LoadingImage.prototype.getIsImageComplete = function() { + return this.img.complete && this.img.naturalWidth !== undefined; + }; + LoadingImage.prototype.confirm = function( isLoaded, message ) { this.isLoaded = isLoaded; - this.emit( 'confirm', this, message ); + this.emit( 'progress', this, this.img, message ); }; // ----- events ----- // @@ -288,6 +325,39 @@ function makeArray( obj ) { eventie.unbind( this.img, 'error', this ); }; + // -------------------------- Background -------------------------- // + + function Background( url, element ) { + this.url = url; + this.element = element; + this.img = new Image(); + } + + // inherit LoadingImage prototype + Background.prototype = new LoadingImage(); + + Background.prototype.check = function() { + eventie.bind( this.img, 'load', this ); + eventie.bind( this.img, 'error', this ); + this.img.src = this.url; + // check if image is already complete + var isComplete = this.getIsImageComplete(); + if ( isComplete ) { + this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' ); + this.unbindEvents(); + } + }; + + Background.prototype.unbindEvents = function() { + eventie.unbind( this.img, 'load', this ); + eventie.unbind( this.img, 'error', this ); + }; + + Background.prototype.confirm = function( isLoaded, message ) { + this.isLoaded = isLoaded; + this.emit( 'progress', this, this.element, message ); + }; + // -------------------------- jQuery -------------------------- // ImagesLoaded.makeJQueryPlugin = function( jQuery ) { diff --git a/sandbox/background/css/background.css b/sandbox/background/css/background.css new file mode 100644 index 0000000..509966a --- /dev/null +++ b/sandbox/background/css/background.css @@ -0,0 +1,29 @@ +.box { + width: 300px; + height: 300px; + margin: 0 20px 20px 0; + border: 1px solid; + display: inline-block; +} + +.orange-tree { + background: url('http://i.imgur.com/bwy74ok.jpg'); + background-size: cover; +} + +.thunder-cloud { + background: url('../../../test/img/thunder-cloud.jpg'); + background-size: contain; +} + +.multi1 { + background: + url("http://i.imgur.com/ZAVN3.png"), + url('http://i.imgur.com/6UdOxeB.png') bottom right, + url(http://i.imgur.com/LkmcILl.jpg); + background-size: cover; +} + +.blue { + background: #09F; +}
\ No newline at end of file diff --git a/sandbox/background/index.html b/sandbox/background/index.html new file mode 100644 index 0000000..d7f02d6 --- /dev/null +++ b/sandbox/background/index.html @@ -0,0 +1,52 @@ +<!doctype html> +<html> +<head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width" /> + + <title>background</title> + + <!-- put in separate folder so JS path is different from CSS path --> + <link rel="stylesheet" href="css/background.css" > + +</head> +<body> + + <h1>background</h1> + +<div class="box orange-tree"></div> + +<div class="box thunder-cloud"></div> + +<div class="box multi1"></div> + +<div class="box blue"></div> + +<script src="../../bower_components/eventEmitter/EventEmitter.js"></script> +<script src="../../bower_components/eventie/eventie.js"></script> +<script src="../../imagesloaded.js"></script> +<script> + +var imgLoad0 = imagesLoaded( '.orange-tree', { background: true }, function() { + console.log('orange tree bg images loaded', imgLoad0.images.length ); +}); + +var imgLoad1 = imagesLoaded( '.thunder-cloud', { background: true }, function() { + console.log('thunder cloud bg images loaded', imgLoad1.images.length); +}); + +var imgLoad2 = imagesLoaded( '.multi1', { background: true }, function() { + console.log('multi1 bg images loaded', imgLoad2.images.length); +}); + +var imgLoad3 = imagesLoaded( '.box', { background: true }, function() { + console.log('.box bg images loaded', imgLoad3.images.length); +}); +imgLoad3.on('progress', function( instance, image, element ) { + console.log( 'progress on .box', image.img.src, element.className ); +}) + +</script> + +</body> +</html> |