[JS P.J] 페이지네이션 구현하기
페이지네이션이란?
페이지네이션은 데이터를 여러 페이지로 나누어 표시하는 것을 말한다.
이 사진을 보면 한 번에 페이지네이션이 무엇인지 이해할 수 있을 것이다!
▶ 페이지네이션 초기 설정값
페이지네이션을 구현하기 위해서는 4가지의 초기 설정값이 필요하다.
- currentPage: 현재 페이지
- totalCount: 총 아이템 개수
- pageCount: 화면에 나타날 페이지 개수
- limit: 한 페이지당 나타낼 아이템 개수
나는 아래와 같이 설정해 주었다.
- currentPage: 1
- totalCount: 10
- pageCount: 6
- limit: 6
▶ 페이지네이션 구현 위한 데이터
▷ 총 페이지 수
총 페이지 수 = 총 아이템 개수 / 한 페이지당 나타낼 아이템 개수
totalCount(총 아이템 개수)를 10이라고 설정해 두었고, limit(한 페이지당 나타낼 아이템 개수)를 6이라고 설정해 두었다.
그럼 총 페이지 수는 아래와 같은 공식으로 계산할 수 있을 것이다.
총 페이지 수 = Math.ceil(totalCount / limit)
Math.ceil(10 / 6) = 2
Math.ceil은 소수값이 존재할 때 값을 올려주는 역할을 하는 함수이다. 올림을 하는 이유는 마지막 페이지에 아이템 개수가 limit의 개수보다 작아도 보여야하기 때문이다.
▷ 화면에 띄울 페이지 그룹
현재 페이지가 몇번째 그룹에 속해있는지를 알아야 현재 페이지 그룹 상의 첫번째 숫자와 마지막 숫자를 구할 수 있기 때문에 화면에 띄울 페이지 그룹을 알아야한다.
화면에 띄울 페이지 그룹 = Math.ceil(현재 페이지 번호 / 한 화면에 보여질 아이템 개수)
예를 들어 2페이지가 존재하고 한 화면에 띄우고 싶은 아이템 개수가 6개이며, 현재 아이템 번호가 7이라고 가정해보자
그렇다면 다음과 같이 페이지 그룹이 구성될 것이다.
- page1 그룹: 1 2 3 4 5 6
- page2에는 그룹: 7 8 9 10
따라서 다음과 같이 계산할 수 있다.
화면에 보여질 페이지 그룹 = Math.ceil(현재 페이지 번호 / 한 화면에 보여질 페이지 개수)
한 화면에 보여질 페이지 그룹 = Math.ceil(7 / 6) = 2
▷ 각 페이지의 첫 번째와 마지막 아이템 번호
현재 페이지 그룹의 첫번째 ~ 마지막 숫자만큼 페이지를 화면에 표시하고, 페이지네이션의 이전, 다음을 구현하기 위해 각 페이지의 첫 번째와 마지막 아이템 번호를 알야아한다.
각 페이지의 첫 번째 아이템 번호 계산하기
각 페이지의 첫 번째 아이템 번호 = ((총 페이지 수 - 1)) * (각 화면에 보여질 아이템 개수) + 1
각 페이지의 마지막 번호 계산하기
각 페이지의 마지막 아이템 번호 = 총 페이지 수 * 각 화면에 보여질 아이템 개수
예를 들어 한 화면에 띄우고 싶은 아이템 개수가 6개이고, 총 아이템 수가 10이라고 가정해보자.
1페이지의 첫 번째 아이템 번호: 1, 마지막 페이지 번호: 6 이 될 것이며, 2페이지의 첫 번째 아이템 번호: 7, 마지막 페이지 번호는 10이 될 것이다.
따라서 첫 번째 페이지 번호와 마지막 페이지 번호는 다음과 같다.
각 페이지의 첫 번째 아이템 번호 = ((2 - 1)) * 6 + 1 = 7
각 페이지의 마지막 아이템 번호 = 2 * 6 = 12
▶ 페이지네이션 구현 실전 예시
이제 페이지네이션을 어떻게 구현하는지에 대한 전반적인 지식을 습득했으니, 해커톤 때 내가 어떤 식으로 페이지네이션을 구현했는지 살펴보자!
위와 같이 라디오(아이템)가 추가될 때마다 특정 위치값에 사진을 추가해야했었는데, 이 부분에서 굉장히 애를 먹다가, 이 유튜브 영상에서 힌트를 얻어 구현을 하였다. https://www.youtube.com/watch?v=yN-YjZVRhME
우선 페이지네이션 js 전체 코드는 아래와 같이 작성해주었다.
// pagenation.js
let thisPage = 1;
const limit = 6;
const list = document.querySelectorAll(".list .item");
function loadItem() {
const beginGet = (thisPage - 1) * limit;
const endGet = thisPage * limit - 1;
list.forEach((item, key) => {
if (key >= beginGet && key <= endGet) {
item.style.display = "block";
} else {
item.style.display = "none";
}
});
listPage();
}
loadItem();
function listPage() {
const count = Math.ceil(list.length / limit);
document.querySelector(".listPage").innerHTML = "";
if (thisPage != 1) {
const prev = document.createElement("li");
prev.innerText = "<<";
prev.setAttribute("onclick", "changePage(" + (thisPage - 1) + ")");
document.querySelector(".listPage").appendChild(prev);
}
for (let i = 1; i <= count; i++) {
const newPage = document.createElement("li");
newPage.innerText = i;
if (i == thisPage) {
newPage.classList.add("active");
}
newPage.setAttribute("onclick", "changePage(" + i + ")");
document.querySelector(".listPage").appendChild(newPage);
}
}
function changePage(i) {
thisPage = i;
loadItem();
}
⭐위에서 설명했듯 페이지네이션을 구현하기 위해서 아래와 같은 데이터가 필요했다.
- 총 페이지 수 ( = 전체 아이템 개수 / 한 화면에 띄우고 싶은 아이템 개수 )
- 화면에 띄울 페이지 그룹 ( = Math.ceil(현재 페이지 번호 / 한 화면에 보여질 아이템 개수) )
- 각 페이지의 첫 번째 아이템 번호 ( = ((총 페이지 수 - 1)) * (각 화면에 보여질 아이템 개수) + 1 )
- 각 페이지의 마지막 아이템 번호 ( = 총 페이지 수 * 각 화면에 보여질 아이템 개수 )
이 점을 중점으로 코드를 하나하나 분석해보도록 하자!
변수선언
- thisPage: 현재 표시되는 페이지 ( 초기값 = 1 )
- limit: 한 페이지당 보여지는 아이템의 수 ( 한 페이지에 6개의 아이템이 보여짐 )
- list: 페이지에 표시될 아이템 선택 ( .list .item 선택자에 해당하는 모든 요소들을 선택 )
let thisPage = 1;
const limit = 6;
const list = document.querySelectorAll(".list .item");
페이지 로드 함수
- beginGet와 endGet 변수는 현재 페이지에 표시해야 할 아이템의 첫 번째 번호 마지막 번호를 계산
- list.forEach 루프를 사용하여 모든 아이템을 순회하며, 현재 페이지에 해당하는 아이템만 display 속성을 “block”으로 설정하여 보여주고 나머지는 “none”으로 설정하여 숨김
function loadItem() {
const beginGet = (thisPage - 1) * limit;
const endGet = thisPage * limit - 1;
list.forEach((item, key) => {
if (key >= beginGet && key <= endGet) {
item.style.display = "block";
} else {
item.style.display = "none";
}
});
listPage();
}
페이지 목록 생성 함수
- 전체 아이템 수를 페이지당 아이템 수로 나누어 페이지 수를 계산
- .listPage라는 클래스를 가진 요소의 HTML을 비우고 새로운 페이지 링크를 생성
- 현재 페이지가 1이 아닌 경우 이전 페이지 버튼(«)을 생성하고 이전 페이지로 이동하는 이벤트를 설정
- for 루프를 사용하여 페이지 번호 버튼을 생성, 현재 페이지인 경우 active 클래스를 추가하여 현재 페이지를 표시
- 페이지 번호 버튼을 클릭하면 해당 페이지로 이동하도록 이벤트를 설정
function listPage() {
const count = Math.ceil(list.length / limit); // 총 페이지 수 계산
document.querySelector(".listPage").innerHTML = ""; // 페이지 번호를 갱신하기 위해 초기화
// 이전 페이지 버튼 생성
if (thisPage != 1) {
const prev = document.createElement("li");
prev.innerText = "<<";
prev.setAttribute("onclick", "changePage(" + (thisPage - 1) + ")");
document.querySelector(".listPage").appendChild(prev);
}
// 페이지 번호 버튼 생성
for (let i = 1; i <= count; i++) {
const newPage = document.createElement("li");
newPage.innerText = i;
if (i == thisPage) {
newPage.classList.add("active");
}
newPage.setAttribute("onclick", "changePage(" + i + ")");
document.querySelector(".listPage").appendChild(newPage);
}
}
페이지 변경 함수
function changePage(i) {
thisPage = i; // 현재 페이지 업데이트
loadItem(); // 새로운 페이지 아이템 로드
}
📎 참조
- https://yonghwankim-dev.tistory.com/578
- https://min-kyung.tistory.com/30
댓글남기기