-
프론트엔드 UI개발 05_Pagination웹개발 2023. 9. 12. 01:05
class Pagination { constructor(commentContainerEl, paginationContainerEl, initialItems = []) { this.currentPageIndex = 0; this.maxPageItemCount = 5; this.commentItems = initialItems; this.commentContainerEl = commentContainerEl; this.paginationContainerEl = paginationContainerEl; this.render(); const onClickButtons = (event) => { /** * 버튼 컨테이너에서 이벤트를 위임받아 처리 */ const { target } = event; if (target.tagName === 'BUTTON') { const index = Number(target.dataset.index); this.setCurrentPageIndex(index); } }; this.paginationContainerEl .addEventListener('click', onClickButtons); } makeCommentsHtml() { const { commentItems, currentPageIndex, maxPageItemCount } = this; const startIndex = currentPageIndex * maxPageItemCount; return commentItems .slice(startIndex, startIndex + maxPageItemCount) .map((item) => { const { id, profile_url, author, content, createdAt } = item; return ( `<div class="commentWrap" data-id="${id}"> <img src="${profile_url}" alt="" /> ${author} <div class="createdAt"> ${createdAt} </div> <div class="content"> ${content} </div> </div> <hr /> ` ); }) .join(''); } makePaginationHtml() { const { commentItems, currentPageIndex, maxPageItemCount, } = this; const count = Math.ceil(commentItems.length / maxPageItemCount); const buttons = []; for (let i = 0; i < count; i++) { buttons.push( i === currentPageIndex ? `<button class="active" data-index=${i}>${(i + 1)}</button>` : `<button data-index=${i}>${(i + 1)}</button>` ); } return buttons.join(''); } render() { const { commentContainerEl, paginationContainerEl } = this; if (commentContainerEl && paginationContainerEl) { commentContainerEl.innerHTML = this.makeCommentsHtml(); paginationContainerEl.innerHTML = this.makePaginationHtml(); return true; } return false; } setCurrentPageIndex(pageIndex) { this.currentPageIndex = pageIndex; this.render(); } } document.addEventListener('DOMContentLoaded', () => { const commentContainerEl = document.querySelector('#commentContainer'); const paginationContainerEl = document.querySelector('#pageContainer'); const pagination = new Pagination(commentContainerEl, paginationContainerEl, comments); })
페이지네이션은 가장 기본적인 정보 탐색 방법이며, 게시판에 주로 사용되는 UI입니다. 아무래도, 예전부터 많이 사용하던 정보제공 방식이기 때문에 어떻게 만들어지는지 알고 있으면, 나머지는 이를 기반으로한 변형이라고 생각됩니다. 가장 중요한 변수 두 가지가 있다면, currentPageIndex와 maxPageItemCount 입니다. 여기서, 기본값으로는 각각 0과 5를 가집니다. 그리고 데이터의 총 길이를 알아야 합니다.
우선 랜더링은 크게 두 부부으로 생각할 수 있습니다. 데이터를 보여주는 테이블 영역과 페이지 버튼 영역입니다. 데이터를 보여주는 리스트 영역을 구현하기 위해서는 현재 index와 max 페이지 값이 필요합니다. 우선 slice()를 사용해서 제공되는 데이터의 길이를 잘라서 보여줘야합니다. 이때 필요한 것이 시작 index와 보여주는 아이템까지의 index값 입니다. 우선, startIndex는 currentPageIndex * maxPageItemCount 를 통해 구합니다. endIndex는 startIndex + maxPageItemCount로 구할 수 있습니다. 이 두 값을 slice()에 넣어주면 데이터에서 화면에 보여지는 만큼만 가져옵니다.
그럼 페이지네이션 하단에 위치한 카운트는 어떻게 처리하면 될까요? 바로 makePaginationHtml() 함수를 사용하면 됩니다. 이때 필요한 변수값들이 있는데요, 전체 아이템, 현재 페이지 index, 최대 카운트 입니다. Math.ceil(commentItems.length / maxPageItemCount)를 통해서 총 count를 구할 수 있습니다. 그리고 현재 index와 동일한 버튼에 active 클래스가 들어간 태그를 랜더링하면 됩니다.
페이징을 하는 버튼이 여러개가 노출되며, 각각에 이벤트를 걸어준 것이 아니라, 부모요소인 paginationContainerEl에 이벤트 함수를 걸고, target.tagName === 'BUTTON'을 선택해서 current index값을 가져와서 값을 업데이트함과 동시에 render()함수를 실행하는 프로세스입니다.
'웹개발' 카테고리의 다른 글
프론트엔드 스터디_블로그 앱 프로젝트 (0) 2023.12.12 프론트엔드 UI개발 06_IntersectionObserver (0) 2023.11.15 프론트엔드 UI개발 04_Instant Search (0) 2023.08.18 프론트엔드 UI개발 03_Dropdown Menu (0) 2023.08.03 프론트엔드 UI개발 02_Draggable Element (0) 2023.06.26