서버 사이드 렌더링을 위한 이미지 슬라이드 구현
# 개발 동기
- 기존 이미지 슬라이드 라이브러리들은 대부분 클라이언트에서 이미지를 렌더링하도록 개발되었기 때문에 서버에서 이미지 슬라이드를 미리 렌더링 할 경우 사용하기 어려움.
- 서버에서 렌더링한 이미지들을 슬라이드 할 수 있는 라이브러리 필요
# 설계
- 기본적으로 필요한 옵션들을 파라미터로 받아서 초기화
- prevButton, nextButton 클릭시 margin-left 값을 조절해서 이미지 슬라이드 구현
- 기존 이미지 슬라이드 라이브러리들은 대부분 클라이언트에서 이미지를 렌더링하도록 개발되었기 때문에 서버에서 이미지 슬라이드를 미리 렌더링 할 경우 사용하기 어려움.
- 서버에서 렌더링한 이미지들을 슬라이드 할 수 있는 라이브러리 필요
# 설계
- 기본적으로 필요한 옵션들을 파라미터로 받아서 초기화
- prevButton, nextButton 클릭시 margin-left 값을 조절해서 이미지 슬라이드 구현
define('slider', ['jquery', 'underscore'],
function ($, _) {
/**
* Slider Module
* @param {Object} params
* @param {Number} params.itemPerPage 페이지당 아이템 개수
* @param {Number} params.itemWidth 아이템 넓이
* @param {String} params.containerId 아이템 컨테이너 id
* @param {String} params.prevButtonClass prevButton class
* @param {String} params.nextButtonClass nextButton class
* @param {String} [params.listContainerParentClass] 아이템 리스트 컨테이너 부모 class
* @constructor
*/
function Slider(params) {
try {
if (isNaN(params.itemPerPage)) {
throw "params.itemPerPage is not a number";
}
if (isNaN(params.itemWidth)) {
throw "params.itemWidth is not a number";
}
if (!params.containerId || !_.isString(params.containerId)) {
throw "params.containerId is not a string";
}
if (!params.prevButtonClass || !_.isString(params.prevButtonClass)) {
throw "params.prevButtonClass is not a string";
}
if (!params.nextButtonClass || !_.isString(params.nextButtonClass)) {
throw "params.nextButtonClass is not a string";
}
} catch(err) {
console.error(err);
return;
}
var defaultOptions = {
itemPerPage: 1,
itemWidth: 100
};
this.options = _.extend({}, defaultOptions, params);
this.containerId = this.options.containerId;
this.$listContainer = $("#"+this.containerId).find('.slider-list-container');
if (params.listContainerParentClass) {
this.$listContainer = $("#"+this.containerId).find('.'+params.listContainerParentClass+' > .slider-list-container');
}
this.prevButtonClass = this.options.prevButtonClass;
this.nextButtonClass = this.options.nextButtonClass;
this.totalItemNum = this.$listContainer.children().size();
this.totalPageNum = Math.ceil(this.totalItemNum / this.options.itemPerPage);
this.listContainerWidth = this.totalItemNum * this.options.itemWidth;
this.pageWidth = this.options.itemPerPage * this.options.itemWidth;
this.$listContainer.css({
"overflow": "hidden",
"width": this.listContainerWidth+"px"
});
this.init();
}
Slider.prototype.init = function() {
this.currentPage = 0;
this.currentPosition = 0;
this.moveTo(this.currentPage);
this.bindHandlers();
};
Slider.prototype.bindHandlers = function() {
var self = this;
$("#"+this.containerId).find("."+this.prevButtonClass).click(function() {
self.prev();
});
$("#"+this.containerId).find("."+this.nextButtonClass).click(function() {
self.next();
});
};
/**
* Slider 페이지 이동하는 메서드
* @param {Number} pageNum 이동할 페이지 번호
*/
Slider.prototype.moveTo = function(pageNum) {
try {
if (isNaN(pageNum)) {
throw "pageNum is not a number";
}
} catch(err) {
console.error(err);
return;
}
this.currentPage = pageNum;
this.currentPosition = -(this.currentPage * this.pageWidth);
this.$listContainer.css("margin-left", this.currentPosition+"px");
};
Slider.prototype.prev = function() {
if (this.currentPage === 0) {
return;
}
this.currentPage = this.currentPage - 1;
this.moveTo(this.currentPage);
};
Slider.prototype.next = function() {
if (this.currentPage === (this.totalPageNum - 1)) {
return;
}
this.currentPage = this.currentPage + 1;
this.moveTo(this.currentPage);
};
return Slider;
});
댓글
댓글 쓰기