1/* ======================================================================== 2 * Responsive Image 3 * 4 * Inspired by: 5 * http://luis-almeida.github.com/unveil 6 * http://verge.airve.com/ 7 * ======================================================================== */ 8 9+function($) { 10 11 // cache img.lazyload collection 12 var $lazyload; 13 14 // VIEWPORT HELPER CLASS DEFINITION 15 // ================================ 16 var viewport; 17 var ViewPort = function(options){ 18 this.viewportWidth = 0; 19 this.viewportHeight = 0; 20 this.options = $.extend({}, ViewPort.DEFAULTS, options); 21 this.attrib = "src"; 22 this.update(); 23 }; 24 25 ViewPort.DEFAULTS = { 26 breakpoints : { 27 0: 'extrasmall', 28 768: 'small', 29 992: 'medium', 30 1321: 'large' 31 } 32 } 33 34 ViewPort.prototype.viewportW = function() { 35 var clientWidth = document.documentElement['clientWidth'], innerWidth = window['innerWidth']; 36 return this.viewportWidth = clientWidth < innerWidth ? innerWidth : clientWidth; 37 }; 38 39 ViewPort.prototype.viewportH = function() { 40 var clientHeight = document.documentElement['clientHeight'], innerHeight = window['innerHeight']; 41 return this.viewportHeight = clientHeight < innerHeight ? innerHeight : clientHeight; 42 }; 43 44 ViewPort.prototype.inviewport = function(boundingbox) { 45 return !!boundingbox && boundingbox.bottom >= 0 && boundingbox.right >= 0 && boundingbox.top <= this.viewportHeight && boundingbox.left <= this.viewportWidth; 46 }; 47 48 ViewPort.prototype.update = function(){ 49 this.viewportH(); 50 this.viewportW(); 51 var attrib = this.attrib, 52 width = this.viewportWidth; 53 54 $.each(this.options.breakpoints, function (breakpoint, datakey) { 55 if (width >= breakpoint) { 56 attrib = datakey; 57 } 58 }); 59 60 this.attrib = attrib; 61 }; 62 63 // expose viewportH & viewportW methods 64 $.fn.viewportH = ViewPort.prototype.viewportH; 65 $.fn.viewportW = ViewPort.prototype.viewportW; 66 67 // RESPONSIVE IMAGES CLASS DEFINITION 68 // ================================== 69 var ResponsiveImage = function(element, options) { 70 this.$element = $(element); 71 this.options = $.extend({}, ResponsiveImage.DEFAULTS, options); 72 this.attrib = "src"; 73 this.loaded = false; 74 this.checkviewport(); 75 }; 76 77 ResponsiveImage.DEFAULTS = { 78 threshold: 0, 79 attrib: "src", 80 skip_invisible: false, 81 preload: false 82 }; 83 84 ResponsiveImage.prototype.checkviewport = function() { 85 if (this.attrib !== viewport.attrib) { 86 this.attrib = viewport.attrib; 87 this.loaded = false; 88 } 89 this.unveil(); 90 }; 91 92 ResponsiveImage.prototype.boundingbox = function() { 93 var boundingbox = {}, 94 coords = this.$element[0].getBoundingClientRect(), 95 threshold = +this.options.threshold || 0; 96 boundingbox['right'] = coords['right'] + threshold; boundingbox['left'] = coords['left'] - threshold; 97 boundingbox['bottom'] = coords['bottom'] + threshold; boundingbox['top'] = coords['top'] - threshold; 98 return boundingbox; 99 }; 100 101 ResponsiveImage.prototype.inviewport = function() { 102 var boundingbox = this.boundingbox(); 103 return viewport.inviewport(boundingbox); 104 }; 105 106 ResponsiveImage.prototype.unveil = function(force) { 107 if (this.loaded || !force && !this.options.preload && this.options.skip_invisible && this.$element.is(":hidden")) return; 108 var inview = force || this.options.preload || this.inviewport(); 109 if (inview) { 110 var query = "(-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)"; 111 if (matchMedia(query).matches) { 112 var source = this.options[this.attrib + 'retina'] || this.options["src"]; 113 } else { 114 var source = this.options[this.attrib] || this.options["src"]; 115 } 116 117 if (source) { 118 this.$element.attr("src", source); 119 this.$element.css("opacity", 1); 120 $(window).trigger('loaded.bk2k.responsiveimage'); 121 this.loaded = true; 122 } 123 } 124 }; 125 126 ResponsiveImage.prototype.print = function() { 127 this.unveil(true); 128 } 129 130 // RESPONSIVE IMAGES PLUGIN DEFINITION 131 // =================================== 132 function Plugin(option) { 133 $lazyload = this; 134 return this.each(function() { 135 var $this = $(this); 136 var data = $this.data('bk2k.responsiveimage'); 137 var options = typeof option === 'object' && option; 138 139 if (!data) { 140 if (!viewport) viewport = new ViewPort(options && options.breakpoints ? {breakpoints:options.breakpoints} : {}); 141 142 if (options && options.breakpoints) options.breakpoints = null; 143 options = $.extend({}, $this.data(), options); 144 145 $this.data('bk2k.responsiveimage', (data = new ResponsiveImage(this, options))); 146 } 147 if (typeof option === 'string') data[option](); 148 }); 149 }; 150 151 var old = $.fn.responsiveimages; 152 $.fn.responsiveimage = Plugin; 153 $.fn.responsiveimage.Constructor = ResponsiveImage; 154 155 // RESPONSIVE IMAGES NO CONFLICT 156 // ============================= 157 $.fn.responsiveimage.noConflict = function() { 158 $.fn.responsiveimage = old; 159 return this; 160 }; 161 162 // RESPONSIVE IMAGES API 163 // ===================== 164 $(window).on('load.bk2k.responsiveimage', function() { 165 $('img.lazyload').responsiveimage(); 166 167 // EVENTS 168 // ====== 169 $(window) 170 .on('scroll.bk2k.responsiveimage', function(){ 171 $lazyload.responsiveimage('unveil'); 172 }) 173 .on('resize.bk2k.responsiveimage', function(){
174 if (viewport) viewport.update(); 175 $lazyload.responsiveimage('checkviewport'); 176 }) 177 .on('beforeprint.bk2k.responsiveimage', function(){ 178 $lazyload.responsiveimage('print'); 179 $(window).trigger("readytoprint.bk2k.responsiveimage"); 180 }); 181 }); 182 183}(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.