간단한 pagination 구현하기

김민아·2022년 7월 20일
1

아고라스테이츠 만들어 보자

목표

  • 한 페이지에 10개의 discussion을 출력한다.
  • 배열의 갯수로 최대 페이지 번호를 출력한다.
  • 페이지를 번호를 누르면 해당 범위의 discussion을 출력한다.

아고라스테이츠 데모 보기

pagination이란?

많은 양의 게시물을 여러 페이지로 나누어 게시물을 분리하는데 필요한 UI 요소이다. 게시판 형태의 콘텐츠 레이아웃에서 쉽게 찾을 수 있다. 사용자는 콘텐츠의 전체 양을 가늠할 수 있고, 스크롤을 하지 않고 적당한 갯수만큼 넘겨 보면서 한 눈에 콘텐츠를 파악할 수 있는 장점이 있다.


간단한 pagination 구현하기

페이징 기능의 일부만 구현해 보았기 때문에 '간단한'이라고 하자!

처음에 가장 고민했던 부분은 배열에 담긴 객체를 어떤 조건으로 범위를 정할 수 있을까. 어떤 방법(메서드)를 사용할 수 있을까였다. 대략 그림으로 보이면 이런 식인데,

붉은색이 배열에 담긴 객체로 총 26개가 있다고 가정해보자.
노란색 묶음은 10개씩 나눈 페이지 그룹이다.
파란색 숫자는 배열의 slice()인덱스를 편의상 표기해본 것이다.

필요한 정보는 다음과 같다.

  • 한 페이지에 보여질 게시물의 갯수 → 10
  • 최대 페이지 번호 → Math.ceil(전체 게시물의 갯수 / 한 페이지에 보여질 게시물 갯수)
  • 현재 페이지 번호 → 현재 클릭한 페이지 번호
  • 현재 페이지 번호에 따른 출력될 배열의 범위 (slice()를 사용해 보기로 했다.)
    startIndex = ((현재 페이지 번호) - 1) * 10
    endIndex = 현재 페이지 번호 * 10

위 그림처럼 2페이지를 출력한다고 하면 currentData = localData.slice(10, 20) 으로 출력할 수 있겠다!

render(element, page)

render함수는 아고라스테이츠에서 로컬스토리지에 저장된 배열을 화면에 출력한다. 역시 이 함수 내에서 createPagination()를 호출하여 pagination 요소를 생성하고 해당 객체만 출력하도록 했다.

또한, 페이지의 번호는 가변적이다. 게시물이 많아지면 페이지도 자동으로 생성되어야 한다.

  1. 출력할 페이지 번호를 page, 총 배열의 갯수를 total 매개변수로 받는다.
  2. page를 매개변수로 받는 이유는 active 클래스를 주어 현재 위치한 페이지를 표시하기 위해서.
  3. pagination 부모 container를 비우고 localData.length를 전달인자로 받아서 totalPageNum을 구한다.
const createPagination = (page, total) => {
  paginationContainer.innerHTML = ''

  let totalPageNum = Math.ceil(total / 10)

	// 페이지 번호만큼 element를 생성한다. 
  for (let i = 1; i <= totalPageNum; i++) {
    const li = document.createElement('li')
    li.classList.add('pagination__list')
    li.textContent = i

    if (li.textContent === String(page)) {
      li.classList.add('active')
    }

		// 생성한 li를 pagination Container에다가 append시킨다. 
    paginationContainer.append(li)
  }
  return
}

Discussion을 나열

배열의 갯수만큼이 아니라 페이지 범위만큼만 출력하도록 수정한다.

let startIndex = (page - 1) * 10
let endIndex = page * 10
let currentPageData = localData.slice(startIndex, endIndex)

for (let i = 0; i < currentPageData.length; i++) {
  element.append(convertToDiscussion(currentPageData[i]));
}

페이지 번호를 클릭시 eventHandler

createPagination()

페이지 번호를 만들 때 click 이벤트를 추가해 준다.

li.addEventListener('click', reRender)

reRender()

클릭한 event.target의 번호를 가져와 몇번째 페이지인지 구분한다.

사실 이렇게 작성하는게 맞는지 약간은 의문. 다른 방법은 못찾아서.

const reRender = (event) => {
  render(ul, event.target.textContent)
}

사실 욕심같아서는 페이지 번호를 5개까지만 보여주고 이전/다음 버튼 기능까지 추가하고 싶었는데, 지금은 무리무리다

0개의 댓글