많은 양의 게시물을 여러 페이지로 나누어 게시물을 분리하는데 필요한 UI 요소이다. 게시판 형태의 콘텐츠 레이아웃에서 쉽게 찾을 수 있다. 사용자는 콘텐츠의 전체 양을 가늠할 수 있고, 스크롤을 하지 않고 적당한 갯수만큼 넘겨 보면서 한 눈에 콘텐츠를 파악할 수 있는 장점이 있다.
페이징 기능의 일부만 구현해 보았기 때문에 '간단한'이라고 하자!
처음에 가장 고민했던 부분은 배열에 담긴 객체를 어떤 조건으로 범위를 정할 수 있을까. 어떤 방법(메서드)를 사용할 수 있을까였다. 대략 그림으로 보이면 이런 식인데,
붉은색이 배열에 담긴 객체로 총 26개가 있다고 가정해보자.
노란색 묶음은 10개씩 나눈 페이지 그룹이다.
파란색 숫자는 배열의 slice()
인덱스를 편의상 표기해본 것이다.
10
Math.ceil(전체 게시물의 갯수 / 한 페이지에 보여질 게시물 갯수)
현재 클릭한 페이지 번호
((현재 페이지 번호) - 1) * 10
현재 페이지 번호 * 10
위 그림처럼 2페이지를 출력한다고 하면
currentData = localData.slice(10, 20)
으로 출력할 수 있겠다!
render
함수는 아고라스테이츠에서 로컬스토리지에 저장된 배열을 화면에 출력한다. 역시 이 함수 내에서 createPagination()
를 호출하여 pagination 요소를 생성하고 해당 객체만 출력하도록 했다.
또한, 페이지의 번호는 가변적이다. 게시물이 많아지면 페이지도 자동으로 생성되어야 한다.
page
, 총 배열의 갯수를 total
매개변수로 받는다. page
를 매개변수로 받는 이유는 active
클래스를 주어 현재 위치한 페이지를 표시하기 위해서. 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
}
배열의 갯수만큼이 아니라 페이지 범위만큼만 출력하도록 수정한다.
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]));
}
페이지 번호를 만들 때 click 이벤트를 추가해 준다.
li.addEventListener('click', reRender)
클릭한 event.target
의 번호를 가져와 몇번째 페이지인지 구분한다.
사실 이렇게 작성하는게 맞는지 약간은 의문. 다른 방법은 못찾아서.
const reRender = (event) => {
render(ul, event.target.textContent)
}
사실 욕심같아서는 페이지 번호를 5개까지만 보여주고 이전/다음 버튼 기능까지 추가하고 싶었는데, 지금은 무리무리다
끗