angular-lazy-image
Version:
Loading responsive image when container (which is preventing reflow) is in view.
1 lines • 4.98 kB
JavaScript
angular.module("afkl.lazyImage",[]),angular.module("afkl.lazyImage").service("afklSrcSetService",["$window",function(a){"use strict";function b(a){this.src=a.src,this.w=a.w||1/0,this.h=a.h||1/0,this.x=a.x||1}function c(a,b){var c,d;return function(){var e=+new Date;c&&e<c+b?(clearTimeout(d),d=setTimeout(function(){c=e,a()},b+c-e)):(c=e,a())}}var d=/^[0-9]+$/,e=function(a){for(var b=a.split(/\s/),c={},e=0,f=b.length;e<f;e++){var g=b[e];if(g.length>0){var h=g.slice(-1),i=g.substring(0,g.length-1),j=parseInt(i,10),k=parseFloat(i);i.match(d)&&"w"===h?c[h]=j:i.match(d)&&"h"===h?c[h]=j:isNaN(k)||"x"!==h||(c[h]=k)}}return c},f=function(a,b){for(var c=a[0],d=0,e=a.length;d<e;d++){var f=a[d];b(f,c)&&(c=f)}return c},g=function(a,b){for(var c=a.length-1;c>=0;c--){var d=a[c];b(d)&&a.splice(c,1)}return a},h=function(b,c){if(b){c||(c={w:a.innerWidth||document.documentElement.clientWidth,h:a.innerHeight||document.documentElement.clientHeight,x:a.devicePixelRatio||1});var d=b.slice(0),e=f(d,function(a,b){return a.w>b.w});g(d,function(){return function(a){return a.w<c.w}}(this)),0===d.length&&(d=[e]);var h=f(d,function(a,b){return a.h>b.h});g(d,function(){return function(a){return a.h<c.h}}(this)),0===d.length&&(d=[h]);var i=f(d,function(a,b){return a.x>b.x});g(d,function(){return function(a){return a.x<c.x}}(this)),0===d.length&&(d=[i]);var j=f(d,function(a,b){return a.w<b.w});g(d,function(a){return a.w>j.w});var k=f(d,function(a,b){return a.h<b.h});g(d,function(a){return a.h>k.h});var l=f(d,function(a,b){return a.x<b.x});return g(d,function(a){return a.x>l.x}),d[0]}},i=function(a){var c=[],d=a.src,f=a.srcset;if(f){var g=function(a){for(var b=0,d=c.length;b<d;b++){var e=c[b];if(e.x===a.x&&e.w===a.w&&e.h===a.h)return}c.push(a)},i=function(){for(var a,c,h=f,i=0,j=[];""!==h;){for(;" "===h.charAt(0);)h=h.slice(1);i=h.indexOf(" "),i!==-1?(a=h.slice(0,i),h=h.slice(i+1),i=h.indexOf(","),i===-1?(c=h,h=""):(c=h.slice(0,i),h=h.slice(i+1)),j.push({url:a,descriptors:c})):(j.push({url:h,descriptors:""}),h="")}for(var k=0,l=j.length;k<l;k++){var m=j[k],n=e(m.descriptors);g(new b({src:m.url,x:n.x,w:n.w,h:n.h}))}d&&g(new b({src:d}))};i();var j=h(c),k={best:j,candidates:c};return c=null,k}};return{get:i,image:h,throttle:c}}]),angular.module("afkl.lazyImage").directive("afklImageContainer",function(){"use strict";return{restrict:"A",controller:["$scope","$element",function(a,b){b.data("afklImageContainer",b)}]}}).directive("afklLazyImage",["$rootScope","$window","$timeout","afklSrcSetService","$parse",function(a,b,c,d,e){"use strict";var f=function(a){var b,c=d.get({srcset:a});return c&&(b=c.best.src),b};return{restrict:"A",link:function(g,h,i){var j=function(a){var b=[],c="afkl-lazy-image",d=!1;return o.imgAttrs&&(b=Array.prototype.map.call(a,function(a){for(var b in a)if(a.hasOwnProperty(b)){var e=a[b];return"class"===b&&(d=!0,e=e+" "+c),String.prototype.concat.call(b,'="',e,'"')}})),d||b.push('class="'+c+'"'),b.join(" ")},k=h.inheritedData("afklImageContainer");k||(k=angular.element(i.afklLazyImageContainer||b));var l,m=!1,n=i.afklLazyImage,o=i.afklLazyImageOptions?e(i.afklLazyImageOptions)(g):{},p=null,q=null,r=o.offset?o.offset:50,s=j(o.imgAttrs),t="afkl-lazy-image-loading";i.afklLazyImageLoaded=!1;var u=function(){if(k.scrollTop){var a=k.scrollTop();if(a)return a}var b=k[0];return void 0!==b.pageYOffset?b.pageYOffset:void 0!==b.scrollTop?b.scrollTop:document.documentElement.scrollTop||0},v=function(){if(k.innerHeight)return k.innerHeight();var a=k[0];return void 0!==a.innerHeight?a.innerHeight:void 0!==a.clientHeight?a.clientHeight:document.documentElement.clientHeight||0},w=function(){if(h.offset)return h.offset().top;var a=h[0].getBoundingClientRect();return a.top+u()-document.documentElement.clientTop},x=function(){return h.offset?h.offset().top-k.offset().top:h[0].getBoundingClientRect().top-k[0].getBoundingClientRect().top},y=function(){o.background?h[0].style.backgroundImage='url("'+q+'")':p&&(p[0].src=q)},z=function(){m=!0;var a=f(n);a&&(o.background||p||(h.addClass(t),p=angular.element("<img "+s+" />"),p.one("load",B),p.one("error",C),h.append(p)),A()),k.off("scroll",D)},A=function(){if(m){var a=f(n);a!==q&&(q=a,y())}};A();var B=function(){i.$set("afklLazyImageLoaded","done"),h.removeClass(t)},C=function(){i.$set("afklLazyImageLoaded","fail")},D=function(){if(!m){var a,c,d,e=v(),f=u(),g=k[0]===b?w():x();d=k[0]===b?e+f:e,a=g-d,c=a<=r,c&&z()}},E=d.throttle(D,300),F=function(){c.cancel(l),l=c(function(){A(),D()},300)},G=function(){c.cancel(l),angular.element(b).off("resize",F),angular.element(b).off("scroll",E),k[0]!==b&&(k.off("resize",F),k.off("scroll",E)),p&&p.remove(),p=l=q=void 0};return angular.element(b).on("resize",F),angular.element(b).on("scroll",E),k[0]!==b&&(k.on("resize",F),k.on("scroll",E)),i.$observe("afklLazyImage",function(){n=i.afklLazyImage,m&&z()}),o.nolazy&&z(),g.$on("afkl.lazyImage.destroyed",F),g.$on("$destroy",function(){return a.$broadcast("afkl.lazyImage.destroyed"),G()}),D()}}}]);