diff --git a/Imager.js b/Imager.js index 19d3c1b..3cad816 100644 --- a/Imager.js +++ b/Imager.js @@ -124,6 +124,7 @@ this.widthsMap = {}; this.refreshPixelRatio(); this.widthInterpolator = opts.widthInterpolator || returnFn; + this.cssBackgrounds = opts.cssBackgrounds || false; // Needed as IE8 adds a default `width`/`height` attribute… this.gif.removeAttribute('height'); @@ -161,7 +162,13 @@ if (elements && elements.length) { var additional = applyEach(elements, returnFn); - this.changeDivsToEmptyImages(additional); + + if (!this.cssBackgrounds) { + this.changeDivsToEmptyImages(additional); + } else { + this.prepareCssBackground(additional); + } + this.divs = this.divs.concat(additional); } }; @@ -187,7 +194,12 @@ window.clearInterval(self.interval); } - this.changeDivsToEmptyImages(elements); + if (!this.cssBackgrounds) { + this.changeDivsToEmptyImages(elements); + } else { + this.prepareCssBackground(elements); + } + this.scrolled = false; } }; @@ -266,6 +278,19 @@ } }; + Imager.prototype.prepareCssBackground = function (elements) { + var self = this; + + applyEach(elements, function(element) { + var elementClassName = element.getAttribute('data-class'); + element.className = (elementClassName ? elementClassName + ' ' : '') + self.className; + }); + + if (this.initialized) { + this.checkImagesNeedReplacing(elements); + } + }; + /** * Indicates if an element is an Imager placeholder * @@ -326,9 +351,14 @@ Imager.prototype.replaceImagesBasedOnScreenDimensions = function (image) { var computedWidth, naturalWidth; - naturalWidth = Imager.getNaturalWidth(image); - computedWidth = typeof this.availableWidths === 'function' ? this.availableWidths(image) - : this.determineAppropriateResolution(image); + naturalWidth = Imager.getNaturalWidth(image); + if (!this.cssBackgrounds) { + computedWidth = typeof this.availableWidths === 'function' ? this.availableWidths(image) + : this.determineAppropriateResolution(image); + } else { + computedWidth = typeof this.availableWidths === 'function' ? this.availableWidths(image) + : this.getBackgroundElementWidth(image); + } image.width = computedWidth; @@ -336,15 +366,27 @@ return; } - image.src = this.changeImageSrcToUseNewImageDimensions(image.getAttribute('data-src'), computedWidth); - image.removeAttribute('width'); - image.removeAttribute('height'); + if (!this.cssBackgrounds) { + image.src = this.changeImageSrcToUseNewImageDimensions(image.getAttribute('data-src'), computedWidth); + image.removeAttribute('width'); + image.removeAttribute('height'); + } else { + this.applyBackgroundImage(image, this.changeImageSrcToUseNewImageDimensions(image.getAttribute('data-src'), computedWidth)); + } + }; + + Imager.prototype.applyBackgroundImage = function (image, url) { + image.style.backgroundImage = 'url(' + url + ')'; }; Imager.prototype.determineAppropriateResolution = function (image) { return Imager.getClosestValue(image.getAttribute('data-width') || image.parentNode.clientWidth, this.availableWidths); }; + Imager.prototype.getBackgroundElementWidth = function (element) { + return Imager.getClosestValue(element.clientWidth, this.availableWidths); + }; + /** * Updates the device pixel ratio value used by Imager * diff --git a/test/fixtures/multiple.html b/test/fixtures/multiple.html new file mode 100644 index 0000000..ebdfc69 --- /dev/null +++ b/test/fixtures/multiple.html @@ -0,0 +1,3 @@ +
+
+
diff --git a/test/unit/html-options.js b/test/unit/html-options.js index d81975a..7d71372 100644 --- a/test/unit/html-options.js +++ b/test/unit/html-options.js @@ -17,6 +17,77 @@ describe('Imager.js HTML data-* API', function () { cleanFixtures(fixtures); }); + describe('CSS Background Support', function () { + it('should not replace divs with images', function (done) { + fixtures = loadFixtures('data-src-new'); + var imgr = new Imager({cssBackgrounds: true, availableWidths: [640, 320]}); + + imgr.ready(function () { + applyEach(imgr.divs, function (el) { + expect(el).to.have.property('nodeName', 'DIV'); + }); + + done(); + }); + }); + + it('should apply a css class to cssBackground enables divs', function (done) { + fixtures = loadFixtures('data-src-new'); + var imgr = new Imager({cssBackgrounds: true, availableWidths: [640, 320], className: 'bg-responsive-img image-replace'}); + + imgr.ready(function () { + applyEach(imgr.divs, function (el) { + expect(el.className).to.equal('bg-responsive-img image-replace'); + }); + + done(); + }); + }); + + it('should set the inline background-image', function (done) { + fixtures = loadFixtures('data-src-new'); + var imgr = new Imager({cssBackgrounds: true, availableWidths: [640, 320]}); + + imgr.ready(function () { + var src = applyEach(imgr.divs, function (el) { + return el.getAttribute('style'); + }); + + expect(src).to.eql([ + 'background-image: url(http://localhost:9876/base/test/fixtures/media/C-640.jpg); ', + 'background-image: url(http://localhost:9876/base/test/fixtures/media/B-640.jpg); ', + 'background-image: url(http://localhost:9876/base/test/fixtures/media-640/fillmurray.jpg); ' + ]); + + done(); + }); + }); + + it('should work for both images and background images', function (done) { + fixtures = loadFixtures('multiple'); + var images = document.querySelectorAll('.imager-image'); + var backgrounds = document.querySelectorAll('.responsive-background-image'); + var imageImgr = new Imager(images, {availableWidths: [320, 640]}); + var backgroundImgr = new Imager(backgrounds, {cssBackgrounds: true, availableWidths: [320, 640]}); + + imageImgr.ready(function () { + var src = applyEach(imageImgr.divs, function (el) { + return el.getAttribute('src'); + }); + expect(src).to.eql(['base/test/fixtures/media/C-640.jpg', 'base/test/fixtures/media-320/fillmurray.jpg']); + + backgroundImgr.ready(function () { + var src = applyEach(backgroundImgr.divs, function (el) { + return el.getAttribute('style'); + }); + expect(src).to.eql(['background-image: url(http://localhost:9876/base/test/fixtures/media/B-640.jpg); ']); + done(); + }); + + }); + }); + }); + describe('handling {width} in data-src', function () { it('should not use RegExp anymore', function (done) { fixtures = loadFixtures('data-src-old');