UI Laboratory

UI 개발을 위한 레퍼런스

Lazy Load

설명
lazy load는 가시영역(보이는 곳)의 이미지만 로딩할때 사용된다.
그러므로 브라우저상 에서 스크롤링을 할때 이미지 객체가 가시영역일 경우 로딩이 진행된다.
그러므로 서버의 과부하는 줄여주고 효율적인 로딩시스템을 제공한다.
사용법은 아래와 같다.

HTML

					

CSS

					<style type="text/css">
						.lazy {-webkit-transition-property: opacity; -moz-transition-property: opacity; -o-transition-property: opacity; transition-property: opacity; -webkit-transition-duration: 0.3s; -moz-transition-duration: 0.3s; -o-transition-duration: 0.3s; transition-duration: 0.3s; -webkit-transition-timing-function: ease; -moz-transition-timing-function: ease; -o-transition-timing-function: ease; transition-timing-function: ease; filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0); opacity: 0;}
						.poster li {float:left; width:50%;}
						.poster li h2 {padding-left:10px;line-height:24px;}
					</style>
				

Javascript

<script type="text/javascript">
var eventBridge = $('<div />');
var eventDictionary = {
	global : {
		RESIZE : 'resize',
		 ROTATE : 'rotate',
		 SCROLL : 'scroll'
	 }
};
function scrollTop(){
	return $(window).scrollTop();
}

function calcTop(elem){
	var offset = elem.offset();
	return offset.top
}
/**
  Function to throttle speed of events
  @function throttle
 **/
var throttle = (function () {
	return function (fn, delay) {
		delay || (delay = 100);
		var last = (function () {
				return +new Date();
			})(),
		timeoutId = null;

		return function () {
			var args = arguments;
			if (timeoutId) {
				clearTimeout(timeoutId);
				timeoutId = null;
			}

			var now = (function () {
				return +new Date();
			})();
			if (now - last > delay) {
				fn.apply(this, args);
				last = now;
			} else {
				timeoutId = setTimeout(function () {
					fn.apply(this, args);
				}, delay);
			}
		};
	};
})();
var ticking = false,
	fireScroll = false,
	fireResize = false;

function requestTick(ev) {
	if (!ticking) {
		window.webkitRequestAnimationFrame(function () {
			if (fireScroll) {
				eventBridge.trigger(jQuery.Event(eventDictionary.global.SCROLL)/*, ss.metrics*/);
				fireScroll = false;
			}
			if (fireResize) {
				eventBridge.trigger(jQuery.Event(eventDictionary.global.RESIZE)/*, ss.metrics*/);
				fireResize = false;
			}
			ticking = false;
		});
		ticking = true;
	}
}
(function($){
	$.LazyLoadImages = function(){
		return {
			lazy : [],
			init : function(){
				var self = this;
				//Lazy loaded images
				self.lazy = $('.lazy');
				self.lazy.attr('data-lazy-loaded', 'false');
				self.scan();
				self.bindEvents();
			},
			scan : function(){
				var len = this.lazy.length;
				for(var i=0;i<len;i++){
					var $elem = $(this.lazy[i]);
					if($elem.attr('data-lazy-loaded') !== 'true' && this.isInView($elem)){
						$elem.attr('data-lazy-loaded', 'true');
						$elem.animate({'opacity':1});
						$elem.removeClass('lazy');
					}
				}
			},
			isInView : function(elem){
				if(!elem.is(':visible')){
					return false;	
				}
				var elemTop = calcTop(elem),
					scrollBottom = $(window).height()+scrollTop(),
					threshold = 0;
				if(elemTop < scrollBottom+threshold){
					return true;
				}
				return false;
		   	},
			bindEvents : function(){
				var self = this;
				eventBridge.on(eventDictionary.global.SCROLL, function(e){
					self.scan();
				});
				$(window).on('scroll', throttle(function (e) {
					fireScroll = true;
					if (typeof window.webkitRequestAnimationFrame !== 'undefined') {
						requestTick();
					} else {
						eventBridge.trigger(jQuery.Event(eventDictionary.global.SCROLL)/*, metrics*/);
					}
				}, 250));
			}
		};
	};
}(jQuery));
$(document).ready(function(){
	new $.LazyLoadImages().init();
});
</script>