애매한 잡학사전

자바스크립트 페이징 처리 with jQuery 본문

DEV/jQuery

자바스크립트 페이징 처리 with jQuery

거대한 개발자 2020. 11. 12. 15:22
반응형

javascript, jQuery를 이용한 모바일, PC 동적 페이징 처리하기

현재는 반응형 웹으로 모바일에 맞게 페이징을 '더보기' 형태로 구현 되어있는 프로젝트에서 

 

페이징 처리를 추가해 달라는 요청이 있어서 공통으로 써도 될 것 같아서 구현해 보았습니다. 

 

현재까지 테스트 결과 이상없이 동작하는 것은 확인했는데 

 

아직 미흡하나마 정리해보려고 합니다. 

 

PC와 모바일 확인은 window.innerWidth 로 확인을 해서 530 이상일 경우는 PC 

 

그 이하는 모바일이라고 판단하고 처리하였습니다.

 

 

- HTML 소스

<html>
	<head>
		<script type="text/javascript" src="/js/jquery-1.12.4.min.js"></script>
		<script type="text/javascript" src="/js/paging.js"></script>
	</head>
	<body>
		<form>
			<input type="hidden" name="currPage" />
			<input type="hidden" name="pageSize" />
		</form>
		<div class="listHead">
			.... list head content ....
		</div>
		<div class="listBody">
			.... list body content ....
		</div>
		<div class="listFooter">
			<div class="paginate"></div>
		</div>
	</body>
</html>

다른 부분들은 각각의 프로젝트에 따라 바뀌겠지만 head 에 있는 스크립트와 form에 있는 hidden 

그리고 페이징 처리한 내용을 넣을 paginate 부분은 필수로 넣어야 합니다.

 

 

- JavaScript 소스

<script type="text/javascript">
/* 페이지 이동 ( 페이징 처리 callback 함수 ) */
fncGoLink = function(currPage, pageSize, section){
  $("input[name='currPage']").val(currPage);
  $("input[name='pageSize']").val(pageSize);
  if(section === 'PC') $("#dev_nodeList").empty();
  fncListSearch();	// 목록 조회 함수 호출
};

/* 목록 조회 함수 */
fncListSearch = function(){
  $.ajax({
    type   : 'POST',
    url    : 'searchUrl 세팅';
    data   : $('form').serialize(),
    success: function(data){
      // 페이징 처리 ( parameter : target, 리스트 전체 개수, 리스트 전체, 현재 페이지, callback 함수명 )
      customPaging('.paginate', data.totCnt, data.list, $("input[name='currPage']").val(), 'fncSearchLinkList');
      
      // 리스트 그리기 ...
      // .....
      $('.listBody').append('리스트 html');
    }
  });
};
</script>

fncListSearch 함수에서 ajax로 목록을 조회하고,

 

조회한 전체 건수, 목록, 현재 페이지 번호, 콜백함수 명을 파라미터로 넘겨서 페이징 처리 함수를 호출합니다.

 

paging 또는 customPaging 둘다 호출 가능합니다.

 

 

- 페이징 처리 기본 함수

window.paging = window.customPaging = function(target, totalDataCnt, pagingData, currentPage, callback){
  var windowSize = window.innerWidth;	// 윈도우 사이즈 
  if(windowSize >= pagingObj.windowWidth) pcPaging(target, totalDataCnt, currentPage); // PC 페이징 처리
  else mobileMoreView(target, totalDataCnt, pagingData, currentPage); // MOBILE 더보기 처리
}

기본 함수를 하나 생성 후 윈도우 사이즈를 가져와서 일정 사이즈 이상일 경우에는 PC, 

그 이하일 경우에는 모바일이라고 판단하고 분기를 시켰습니다.

PC와 모바일 각각의 함수는 아래에 paging.js 전체 소스를 참고하시면 될 것 같습니다.

 

- paging.js 소스

paging.js 전체 소스 입니다.

var pagingObj = {};

(function(){
    pagingObj.dataPerPage = 10;     // 한 페이지에 나타낼 데이터 수
    pagingObj.pageCount = 10;       // 한 화면에 나타낼 페이지 수
    pagingObj.prev = 0;             // 이전 페이지 값
    pagingObj.next = 0;             // 다음 페이지 값
    pagingObj.windowWidth = 530;    // 모바일 / PC 확인을 위한 window size

    /**
     * 페이징 처리
     * @param target       = 처리한 페이징 내용을 넣을 대상
     * @param totalDataCnt = 전체 데이터 개수
     * @param pagingData   = 데이터 리스트
     * @param currentPage  = 현재 페이지 번호
     * @param callback     = callback 함수
     */
    window.paging = window.customPaging = function(target, totalDataCnt, pagingData, currentPage, callback){
        var windowSize = window.innerWidth; // PC / 모바일 구분을 위한 윈도우 사이즈 측정

        if(windowSize >= pagingObj.windowWidth) pcPaging(target, totalDataCnt, currentPage); // PC 페이징 처리
        else mobileMoreView(target, totalDataCnt, pagingData, currentPage);  // MOBILE 더보기 처리

        // 페이징 클릭 이벤트
        $(target + ' a').on('click',function(){
            var thisItem = $(this), thisId = thisItem.attr('id'), currPage, pageSize, section;

            if(thisId === 'viewMore'){ // 모바일 더보기
                thisId = thisItem.attr('title');
                currPage = parseInt(thisId) * pagingObj.dataPerPage + 1;
                pageSize = currPage + (pagingObj.dataPerPage - 1);
                section = 'MOBILE';

            } else {    // PC 페이징
                if(thisId === 'next') currPage = pagingObj.next;
                else if(thisId === 'prev') currPage = pagingObj.prev;
                else currPage = parseInt(thisItem.text());

                pageSize = currPage * pagingObj.dataPerPage;
                currPage = currPage * pagingObj.dataPerPage - (pagingObj.dataPerPage - 1);
                section = 'PC';
            }

            //window[callback](currPage, pageSize, section); // 콜백 실행 (ECMAScript 6 이상 사용)
            new Function('return '+callback+'(\''+currPage +'\', \''+ pageSize +'\', \''+section+'\')')()   // 콜백 실행
        });
    };

    var pcPaging = function(target, totalDataCnt, currentPage){
        // 현재 페이지 A tag ID
        curPageId = currentPage>1?Math.round((currentPage/pagingObj.dataPerPage))+1:currentPage;
        
        // 총 페이지 수
        var totalPage = Math.ceil(totalDataCnt/pagingObj.dataPerPage);
        
        // 페이지 그룹
        var pageGroup = Math.ceil(curPageId/pagingObj.pageCount);

        // 화면에 보여질 마지막 페이지 번호
        var last = pageGroup * pagingObj.pageCount;

        // 마지막 페이지 번호가 총 페이지 수 보다 많으면 총 페이지 수 세팅
        if(last > totalPage) last = totalPage;

        // 화면에 보여질 첫번째 페이지 번호
        var first = last - (pagingObj.pageCount-1);

        // 첫페이지가 1보다 작을 경우 1로 세팅
        if(first < 1) first = 1;

        pagingObj.next = last + 1;
        pagingObj.prev = first - 1;

        var pagingHtml = "";

        if(pagingObj.prev > 0) pagingHtml += '<a href="javascript:void(0)" class="prev" id="prev">이전</a>';

        pagingHtml += '<ol>';

        for(var i = first; i <= last; i++){
            pagingHtml += '<li id="'+i+'"><a href="javascript:void(0)" id="pcPaging">'+ i +'</a></li>';
        }

        pagingHtml += '</ol>';

        if(last < totalPage) pagingHtml += '<a href="javascript:void(0)" class="next" id="next">다음</a>';

        // 페이지 목록 생성
        $(target).html(pagingHtml);    
        $(target).addClass('num');  // TODO : 각 프로젝트 스타일에 맞게 수정 및 삭제 필요
        
        // 현재 페이지 표시
        $(target + ' li#'+curPageId).addClass('curpage');  // TODO : 각 프로젝트 스타일에 맞게 수정 및 삭제 필요

        // 데이터 없을 경우 페이징 삭제 처리
        if(totalDataCnt > 0) $(target).show();
        else $(target).hide();
    };

    var mobileMoreView = function(target, totalDataCnt, pagingData, currentPage){
        // 스크롤 세팅
        moreScrollTop = document.documentElement.scrollTop;
        
        // 현재 페이지 num 처리 ( 1, 2, 3, 4.... )
        currentPage = Math.floor(currentPage / (pagingObj.dataPerPage - 1)) + 1;

        // 마지막 페이지 번호
        var lastPage = totalDataCnt % pagingObj.dataPerPage === 0 ? Math.floor(totalDataCnt / pagingObj.dataPerPage) : Math.floor(totalDataCnt / pagingObj.dataPerPage) + 1;

        var pagingHtml = '<a href="javascript:void(0)" class="viewMore" id="viewMore" title="'+ currentPage +'"><span>'+ moreViewTtle +'</span></a>';

        // 페이지 목록 생성
        $(target).html(pagingHtml);

        // 데이터 없을 경우와 마지막 페이지일 경우 페이징 삭제 처리
        if(totalDataCnt > 0 && lastPage !== currentPage) $(target).show();
        else $(target).hide();
    };
})(window);

 

 

- CSS

.paginate {margin-top: 7px;}
.paginate a.viewMore {display: block;cursor: pointer;text-align: center;padding: 12px;color: #3c63e0;}
.paginate a.viewMore span {font-size: 14px;}
.paginate a.viewMore span:after {display: inline-block;content:"";width: 11px;height:10px;margin: 0px 0 0 5px;vertical-align: middle;background:url(../images/common/common_sfix_icon.png) no-repeat -350px 0;}
.paginate a.viewMore.open span:after {display: inline-block;content:"";width: 11px;height:10px;margin: 0px 0 0 5px;vertical-align: middle;background:url(../images/common/common_sfix_icon.png) no-repeat -400px 0;}

.paginate.num {margin-top: 7px;text-align: center;}
.paginate.num > a {display:inline-block;vertical-align:middle;overflow:hidden;width: 37px;height: 36px;font-size:0;text-indent:-120%;color:transparent;background: url("../images/common/common_sfix_icon.png");border: 1px solid #c8c8c8;}
.paginate.num > a.first {background-position:-100px -350px;}
.paginate.num > a.prev {background-position: -236px -188px;margin-right: -4px;border-right: none;}
.paginate.num > a.next {background-position: -285px -188px;margin-left: -4px;border-left: none;}
.paginate.num > a.last {background-position:-250px -350px;}
.paginate.num > a.prev.inactive {background-position: -336px -188px;pointer-events: none;}
.paginate.num > a.next.inactive {background-position: -385px -188px;pointer-events: none;}

.paginate.num ol {display:inline-block;vertical-align:middle;}
.paginate.num ol:after {display:block;content:"";clear:both;}
.paginate.num ol li {float:left;margin-left: -1px;border-top: 1px solid #c8c8c8;border-bottom: 1px solid #c8c8c8;border-left: 1px solid #e7e7e7;border-right: 1px solid #e7e7e7;width: 37px;height: 36px;}
.paginate.num ol li:first-child {margin-left:0;}
.paginate.num ol li a {display:block;width: 100%;height: 100%;line-height: 33px;font-size: 15px;text-align: center;}
.paginate.num ol li a:hover {text-decoration: none;}
.paginate.num ol li.curpage {color: #ffffff;border: 1px solid #303030;background: #555555;}
.paginate.num ol li.curpage a {color: #ffffff;}
.paginate.num ol li.curpage + li {border-left: 1px solid #303030;}
.paginate.num ol li:hover {color: #ffffff;border: 1px solid #303030;background: #555555;}
.paginate.num ol li:hover + li {border-left: 1px solid #303030;}
.paginate.num ol li:hover a {color: #ffffff;}

참고용 CSS 파일 공유합니다. 

PNG 파일 정보가 있는 CSS는 원하는 이미지로 추가하면 됩니다.

 

 

- 결과 

PC 페이징 처리 결과&nbsp;


MOBILE 더보기 처리 결과


 

이상 간단한게 jQuery와 자바스크립트로 페이징 처리를 해봤습니다. 

저도 처음 하는 거라 어색한 부분과 잘못된 부분이 있으면 지적 감사히 받겠습니다. ^^

조금 더 좋은 방법이 있으면 댓글 달아주시면 감사하겠습니다.!

Comments