FRONT/JavaScript

[JS] vanilla js둜 Pagination κ΅¬ν˜„ν•˜κΈ°

eunoia07 2021. 7. 1. 10:59

πŸ€” Pagination?


νŽ˜μ΄μ§€λ„€μ΄μ…˜μ΄λž€ μ½˜ν…μΈ λ₯Ό μ—¬λŸ¬ νŽ˜μ΄μ§€κ³  λ‚˜λˆ„κ³ , 이전 ν˜Ήμ€ λ‹€μŒ νŽ˜μ΄μ§€λ‘œ λ„˜μ–΄κ°€κ±°λ‚˜ νŠΉμ • νŽ˜μ΄μ§€λ‘œ λ„˜μ–΄κ°ˆ 수 μžˆλŠ” 일련의 링크λ₯Ό νŽ˜μ΄μ§€ μƒλ‹¨μ΄λ‚˜ ν•˜λ‹¨μ— λ°°μΉ˜ν•˜λŠ” λ°©λ²•μž…λ‹ˆλ‹€.

 

βœ… ν•„μš”ν•œ Pagination 쑰건


κ²Œμ‹œνŒμ„ 더 μ‰½κ²Œ λ³Ό 수 있고 μ‚¬μš©μžμ˜ 접근성을 높일 수 있게 Pagnation을 μ μš©ν•˜κΈ°λ‘œ ν–ˆμŠ΅λ‹ˆλ‹€.πŸ’ͺ

Pagination을 κ΅¬μƒν•˜λ©΄μ„œ ν•„μš”ν•œ μš”κ΅¬ 쑰건듀은 총 λ„€ κ°€μ§€μž…λ‹ˆλ‹€.

1 ν•œ νŽ˜μ΄μ§€μ— νŽ˜μ΄μ§€ λ§ν¬λŠ” 10개둜 보여쀀닀.
2 ν•œ νŽ˜μ΄μ§€μ— 20κ°œμ”© κ²Œμ‹œλ¬Όμ„ 보여쀀닀.
3 이전, λ‹€μŒ λ²„νŠΌμ΄ μ‘΄μž¬ν•œλ‹€.
4 처음으둜, λ§ˆμ§€λ§‰μœΌλ‘œ λ²„νŠΌμ΄ μ‘΄μž¬ν•œλ‹€.

 

πŸ‘©‍πŸ’» JS둜 Pagination 개발


 

[1. ν•œ νŽ˜μ΄μ§€μ— νŽ˜μ΄μ§€ λ§ν¬λŠ” 10개둜 보여쀀닀.]

total : 462

1 ... 10
11 ... 20
21 ... 23

μœ„μ™€ 같이 νŽ˜μ΄μ§€λ„€μ΄μ…˜μ„ μƒμ„±ν•˜κΈ° μœ„ν•΄μ„œλŠ” λ„€ κ°€μ§€μ˜ 값이 ν•„μš”ν•©λ‹ˆλ‹€.

 

βœ” 화면에 λ³΄μ—¬μ§ˆ νŽ˜μ΄μ§€ κ·Έλ£Ή
βœ” 화면에 λ³΄μ—¬μ§ˆ 첫번째 νŽ˜μ΄μ§€
βœ” 화면에 λ³΄μ—¬μ§ˆ λ§ˆμ§€λ§‰ νŽ˜μ΄μ§€
βœ” 총 νŽ˜μ΄μ§€ 수

 

 

 

πŸ”Ž 총 νŽ˜μ΄μ§€ μˆ˜μ™€ 화면에 λ³΄μ—¬μ§ˆ νŽ˜μ΄μ§€ 그룹은 κ²Œμ‹œλ¬Ό 전체 κ°œμˆ˜μ™€ ν˜„μž¬ νŽ˜μ΄μ§€λ₯Ό μ΄μš©ν•΄ κ΅¬ν•©λ‹ˆλ‹€.

총 νŽ˜μ΄μ§€ 수 = Math.ceil(전체 개수/ ν•œ νŽ˜μ΄μ§€μ— λ‚˜νƒ€λ‚Ό 데이터 수);
화면에 λ³΄μ—¬μ§ˆ νŽ˜μ΄μ§€ κ·Έλ£Ή = Math.ceil(ν˜„μž¬ νŽ˜μ΄μ§€/ ν•œ 화면에 λ‚˜νƒ€λ‚Ό νŽ˜μ΄μ§€ 수);

 

 

πŸ”Ž 화면에 그렀질 첫 번째 νŽ˜μ΄μ§€μ™€ λ§ˆμ§€λ§‰ νŽ˜μ΄μ§€ λŠ” μœ„μ—μ„œ κ΅¬ν•œ 화면에 λ³΄μ—¬μ§ˆ νŽ˜μ΄μ§€ 그룹을 μ΄μš©ν•΄ λ₯Ό κ΅¬ν•©λ‹ˆλ‹€.

화면에 그렀질 첫 번째 νŽ˜μ΄μ§€ : 화면에 그렀질 λ§ˆμ§€λ§‰ νŽ˜μ΄μ§€ - (ν•œ 화면에 λ‚˜νƒ€λ‚Ό νŽ˜μ΄μ§€ - 1)
    (단, κ³„μ‚°λœ 값이 0 μ΄ν•˜μ΄λ©΄ 첫번째 νŽ˜μ΄μ§€λŠ” 1이닀.)

화면에 그렀질 λ§ˆμ§€λ§‰ νŽ˜μ΄μ§€ : 화면에 λ³΄μ—¬μ§ˆ νŽ˜μ΄μ§€ κ·Έλ£Ή * ν•œ 화면에 λ‚˜νƒ€λ‚Ό νŽ˜μ΄μ§€
    (단, κ³„μ‚°λœ 값이 총 νŽ˜μ΄μ§€μˆ˜λ³΄λ‹€ 많으면 λ§ˆμ§€λ§‰ νŽ˜μ΄μ§€λŠ” 은 총 νŽ˜μ΄μ§€ μˆ˜μ΄λ‹€.)

 

μ΄λ ‡κ²Œ λ„€ κ°€μ§€ κ°’μ˜ 계산이 λλ‚¬μŠ΅λ‹ˆλ‹€.

 

 

 

이제, 이 λ„€ κ°€μ§€ 값을 μ΄μš©ν•΄ Pagination을 DOM에 κ·Έλ €μ€λ‹ˆλ‹€.

renderPagination: function (currentPage) {
    // ν˜„μž¬ κ²Œμ‹œλ¬Όμ˜ 전체 κ°œμˆ˜κ°€ 20개 μ΄ν•˜λ©΄ pagination을 μˆ¨κΉλ‹ˆλ‹€.
    if (_totalCount <= 20) return; 

    var totalPage = Math.ceil(_totalCount / 20);
    var pageGroup = Math.ceil(currentPage / 10);

    var last = pageGroup * 10;
    if (last > totalPage) last = totalPage;
    var first = last - (10 - 1) <= 0 ? 1 : last - (10 - 1);

    const fragmentPage = document.createDocumentFragment();
  if (prev > 0) {
      var allpreli = document.createElement('li');
      allpreli.insertAdjacentHTML("beforeend", `<a href='#js-bottom' id='allprev'>&lt;&lt;</a>`);

      var preli = document.createElement('li');
      preli.insertAdjacentHTML("beforeend", `<a href='#js-ottom' id='prev'>&lt;</a>`);

      fragmentPage.appendChild(allpreli);
      fragmentPage.appendChild(preli);
    }

  for (var i = first; i <= last; i++) {
      const li = document.createElement("li");
      li.insertAdjacentHTML("beforeend", `<a href='#js-bottom' id='page-${i}' data-num='${i}'>${i}</a>`);
      fragmentPage.appendChild(li);
  }

  if (last < totalPage) {
      var allendli = document.createElement('li');
      allendli.insertAdjacentHTML("beforeend", `<a href='#js-bottom'  id='allnext'>&gt;&gt;</a>`);

      var endli = document.createElement('li');
      endli.insertAdjacentHTML("beforeend", `<a  href='#js-bottom'  id='next'>&gt;</a>`);

      fragmentPage.appendChild(endli);
      fragmentPage.appendChild(allendli);
  }

    document.getElementById('js-pagination').appendChild(fragmentPage);
        // νŽ˜μ΄μ§€ λͺ©λ‘ 생성
}

 

[2. ν•œ νŽ˜μ΄μ§€μ— 20κ°œμ”© κ²Œμ‹œλ¬Όμ„ 보여쀀닀.]

1νŽ˜μ΄μ§€ : 20개
2νŽ˜μ΄μ§€ : 40개
3νŽ˜μ΄μ§€ : 60개
.
.
.
NνŽ˜μ΄μ§€ : (N * 20)개

각 νŽ˜μ΄μ§€λ§ˆλ‹€ 20κ°œμ”© κ²Œμ‹œλ¬Όμ„ 보여주기 μœ„ν•΄ νŽ˜μ΄μ§€ 번호λ₯Ό μ„œλ²„λ‘œ 전솑해 page에 따라 20κ°œμ”© κ²°κ³Όλ₯Ό λ°›μŠ΅λ‹ˆλ‹€.

πŸ”Ž νŽ˜μ΄μ§€λ„€μ΄μ…˜ νŽ˜μ΄μ§€λ₯Ό ν΄λ¦­ν–ˆμ„ λ•Œ 이벀트λ₯Ό 등둝해 νŽ˜μ΄μ§€ 숫자λ₯Ό μ„œλ²„λ‘œ λ„˜κ²¨μ€λ‹ˆλ‹€.

$("#js-pagination a").click(function (e) {
    e.preventDefault();
    var $item = $(this);
    var $id = $item.attr("id");
    var selectedPage = $item.text();

    list.renderPagination(selectedPage);//νŽ˜μ΄μ§€λ„€μ΄μ…˜ κ·Έλ¦¬λŠ” ν•¨μˆ˜
    list.search(selectedPage);//νŽ˜μ΄μ§€ κ·Έλ¦¬λŠ” ν•¨μˆ˜
});

βœ” μ„œλ²„λ‘œ μ „μ†‘λœ νŽ˜μ΄μ§€ 숫자λ₯Ό μ΄μš©ν•΄ startNum을 νŽ˜μ΄μ§€ 숫자둜 λ°›κ³  endNum 을 νŽ˜μ΄μ§€ 숫자 * 20을 ν•΄ 쿼리λ₯Ό μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€.

SELECT *
FROM (
    SELECT ROW_NUMBER() OVER (/**orderby**/) NUM, LIST.*
    FROM DAMS_PGM_EPISODE_VIEW LIST
    /**where**/
)
WHERE NUM BETWEEN :startRow  AND :endRow 
ORDER BY NUM

μ΄λ ‡κ²Œ 되면 20κ°œμ”© κ²Œμ‹œλ¬Όμ΄ νŽ˜μ΄μ§€μ— 맞게 가져와 μ§‘λ‹ˆλ‹€.

 

[3. 이전, λ‹€μŒ λ²„νŠΌμ΄ μ‘΄μž¬ν•œλ‹€.]

이전 λ²„νŠΌ : 화면에 κ·Έλ €μ§„ 첫번째 νŽ˜μ΄μ§€ - 1
λ‹€μŒ λ²„νŠΌ : 화면에 κ·Έλ €μ§„ λ§ˆμ§€λ§‰ νŽ˜μ΄μ§€ + 1

 

 

 

πŸ”Ž λ²„νŠΌμ„ ν΄λ¦­ν–ˆμ„ λ•Œ νŽ˜μ΄μ§€ μˆ«μžκ°€ μ•„λ‹Œ next prev이면 μ•Œλ§žκ²Œ κ³„μ‚°λœ 값을 νŽ˜μ΄μ§€ 숫자둜 λ„˜κ²¨μ€λ‹ˆλ‹€.

var next = last + 1;
var prev = first - 1;

$("#js-pagination a").click(function (e) {
  e.preventDefault();
  var $item = $(this);
  var $id = $item.attr("id");
  var selectedPage = $item.text();

  if ($id == "next") selectedPage = next;
  if ($id == "prev") selectedPage = prev;

  list.renderPagination(selectedPage);//νŽ˜μ΄μ§€λ„€μ΄μ…˜ κ·Έλ¦¬λŠ” ν•¨μˆ˜
  list.search(selectedPage);//νŽ˜μ΄μ§€ κ·Έλ¦¬λŠ” ν•¨μˆ˜
});

 

[4. 처음으둜, λ§ˆμ§€λ§‰μœΌλ‘œ λ²„νŠΌμ΄ μ‘΄μž¬ν•œλ‹€.]

처음으둜 λ²„νŠΌ : 1
λ§ˆμ§€λ§‰μœΌλ‘œ λ²„νŠΌ : 총 νŽ˜μ΄μ§€ 수

 

 

πŸ”Ž λ²„νŠΌμ„ ν΄λ¦­ν–ˆμ„ λ•Œ νŽ˜μ΄μ§€ μˆ«μžκ°€ μ•„λ‹Œ 첫번째 νŽ˜μ΄μ§€μ™€ λ§ˆμ§€λ§‰ νŽ˜μ΄μ§€λ₯Ό λ„˜κ²¨μ€λ‹ˆλ‹€.

$("#js-pagination a").click(function (e) {
  e.preventDefault();
  var $item = $(this);
  var $id = $item.attr("id");
  var selectedPage = $item.text();

  if ($id == "next") selectedPage = next;
  if ($id == "prev") selectedPage = prev;
  if ($id == "allprev") selectedPage = 1;
  if ($id == "allnext") selectedPage = totalPage;

  list.renderPagination(selectedPage);//νŽ˜μ΄μ§€λ„€μ΄μ…˜ κ·Έλ¦¬λŠ” ν•¨μˆ˜
  list.search(selectedPage);//νŽ˜μ΄μ§€ κ·Έλ¦¬λŠ” ν•¨μˆ˜
});

μ΅œμ’… κ²°κ³Ό ✌


 

[μ΅œμ’… μ½”λ“œ πŸ‘€]

function renderPagination(currentPage) {
  if (_totalCount <= 20) return; 

  var totalPage = Math.ceil(_totalCount / 20);
  var pageGroup = Math.ceil(currentPage / 10);

  var last = pageGroup * 10;
  if (last > totalPage) last = totalPage;
  var first = last - (10 - 1) <= 0 ? 1 : last - (10 - 1);
  var next = last + 1;
  var prev = first - 1;

  const fragmentPage = document.createDocumentFragment();
  if (prev > 0) {
    var allpreli = document.createElement('li');
    allpreli.insertAdjacentHTML("beforeend", `<a href='#js-bottom' id='allprev'>&lt;&lt;</a>`);

    var preli = document.createElement('li');
      preli.insertAdjacentHTML("beforeend", `<a href='#js-bottom' id='prev'>&lt;</a>`);

      fragmentPage.appendChild(allpreli);
      fragmentPage.appendChild(preli);
  }

  for (var i = first; i <= last; i++) {
    const li = document.createElement("li");
    li.insertAdjacentHTML("beforeend", `<a href='#js-bottom' id='page-${i}' data-num='${i}'>${i}</a>`);
    fragmentPage.appendChild(li);
  }

  if (last < totalPage) {
    var allendli = document.createElement('li');
    allendli.insertAdjacentHTML("beforeend", `<a href='#js-bottom'  id='allnext'>&gt;&gt;</a>`);

    var endli = document.createElement('li');
    endli.insertAdjacentHTML("beforeend", `<a  href='#js-program-detail-bottom'  id='next'>&gt;</a>`);

    fragmentPage.appendChild(endli);
    fragmentPage.appendChild(allendli);
  }

  document.getElementById('js-pagination').appendChild(fragmentPage);
  // νŽ˜μ΄μ§€ λͺ©λ‘ 생성

  $(`#js-pagination a`).removeClass("active");
  $(`#js-pagination a#page-${currentPage}`).addClass("active");

  $("#js-pagination a").click(function (e) {
    e.preventDefault();
    var $item = $(this);
    var $id = $item.attr("id");
    var selectedPage = $item.text();

    if ($id == "next") selectedPage = next;
    if ($id == "prev") selectedPage = prev;
    if ($id == "allprev") selectedPage = 1;
    if ($id == "allnext") selectedPage = totalPage;

    list.renderPagination(selectedPage);//νŽ˜μ΄μ§€λ„€μ΄μ…˜ κ·Έλ¦¬λŠ” ν•¨μˆ˜
    list.search(selectedPage);//νŽ˜μ΄μ§€ κ·Έλ¦¬λŠ” ν•¨μˆ˜
  });
};