라이브러리 만들기

페이지네이션 구현하기

ture403 2024. 3. 15. 17:11

- Frederick Philips Brooks
Mythical Man-Month 저자
728x90
반응형

 

<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8" />
    <title>Pagination</title>
    <!-- Styles -->
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        .article {
            max-width: 960px;
            margin: 0 auto;
            padding: 2rem;
            text-align: center;
        }
        .buttons {
            margin-top: 20px;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        button {
            width: 50px;
            height: 50px;
        }

        button.active {
            background-color: #333;
            color: #fff;
        }

        .contents li {
            display: flex;
            align-items: center;
            justify-content: center;
            padding-bottom: 10px;
        }
    </style>
</head>

<body>
    <article class="article">
        <ul class="contents"></ul>
        <div class="buttons">
            <button id="first" data-page=first> &lt&lt; </button>
            <button id="prev" data-page=prev> &lt; </button>
            <div class="render"></div>
            <button id="next" data-page=next> &gt; </button>
            <button id="end" data-page=end> &gt&gt; </button>
        </div>
    </article>
    <!-- Scripts -->
    <script>
        let objectTest = [];
        for (let i = 0; i < 178; i++) {
            objectTest.push({
                list: i + 1,
                main: "홍길동 입니다."
            })
        }
    </script>
    <script>
        const contents = document.querySelector(".contents");
        const render = document.querySelector(".render");
        const next = document.querySelector("#next");
        const prev = document.querySelector("#prev");
        const first = document.querySelector("#first");
        const end = document.querySelector("#end");

        const numOfContent = objectTest.length; //전체 글의 개수
        const maxContent = 10; //화면에 보여질 목록갯수
        const maxButton = 5; //화면에 보여질 페이지 갯수
        const maxPage = Math.ceil(numOfContent / maxContent); //총 페이지 갯수
        const dividedObjects = divideObjects(objectTest, maxContent); //화면에 보여질 리스트 maxContent 만큼 배열 만듬
        let page = 1; //현재페이지 번호
        let pageGroup = Math.ceil(page / maxButton); // 한 화면에 보여질 페이지 그룹
        let pagefirst = ((pageGroup - 1) * maxButton) + 1; //어떤 한 페이지에 첫번째 페이지 번호
        let pagelast = pageGroup * maxButton; ////어떤 한 페이지에 마지막 페이지 번호0,00

        renderPage()
        renderList(0)

        next.addEventListener("click", () => {
            if (pagelast <= maxPage) {
                page = pagelast + 1;
                pageGroup = Math.ceil(page / maxButton);
                pagefirst = ((pageGroup - 1) * maxButton) + 1;
                pagelast = Math.min(maxPage, pageGroup * maxButton);
                renderPage();
                renderList(pagefirst-1);
            }
        })
        prev.addEventListener("click", () => {
            if (page > 1) {
                page = Math.max(1, page - maxButton);
                pageGroup = Math.ceil(page / maxButton);
                pagefirst = ((pageGroup - 1) * maxButton) + 1;
                pagelast = Math.min(maxPage, pageGroup * maxButton);
                console.log("pagefirst", pagefirst)
                console.log("pagelast", pagelast)
                renderPage();
                renderList(pagelast - 1);
            }
        })

        first.addEventListener("click", () => {
            page = 1
            pageGroup = Math.ceil(page / maxButton);
            pagefirst = ((pageGroup - 1) * maxButton) + 1;
            pagelast = pageGroup * maxButton;
            renderPage();
            renderList(page - 1);
        })

        end.addEventListener("click", () => {
            page = maxPage
            pageGroup = Math.ceil(page / maxButton);
            pagefirst = ((pageGroup - 1) * maxButton) + 1;
            pagelast = Math.min(maxPage, pageGroup * maxButton);
            renderPage();
            renderList(pagelast -1)
           
            render.firstChild.classList.remove("active");
            render.lastChild.classList.add("active")
        })

        //이벤트 바인딩
        render.addEventListener("click", (event) => {
            const target = event.target;
            if (target.tagName === "BUTTON") {
                Array.from(render.children).forEach(child => {
                    if (child.classList.contains("active")) {
                        child.classList.remove("active");
                    }
                });

                target.classList.add("active");

                const number = parseInt(target.dataset.page, 10) - 1;
                renderList(number);
            }
        });

        function renderPage() {
            let html = '';
            let pagesToShow = Math.min(maxButton, maxPage - pagefirst + 1);
            for (let i = pagefirst; i < pagefirst + pagesToShow; i++) {
                if (i === pagefirst) {
                    html += `<button class="active" data-page=${i}>${i}</button>`;
                } else {
                    html += `<button data-page=${i}>${i}</button>`;
                }
            }
            render.innerHTML = html
        }

        function divideObjects(objects, batchSize) {
            var dividedObjects = [];
            var currentIndex = 0;

            while (currentIndex < objects.length) {
                var batch = objects.slice(currentIndex, currentIndex + batchSize);
                dividedObjects.push(batch);
                currentIndex += batchSize;
            }

            return dividedObjects;
        }

        function renderList(number) {
            let html = '';
            const lists = dividedObjects[number];

            for (let i = 0; i < lists.length; i++) {
                html += `<li><span>${lists[i].list}</span><p>${lists[i].main}</p><li>`
            }
            contents.innerHTML = html
        }
    </script>
    <!-- <script>
        class Paginator {
            constructor(contentsSelector, renderSelector, numOfContent, maxContent, maxButton) {
                this.contents = document.querySelector(contentsSelector);
                this.render = document.querySelector(renderSelector);
                this.numOfContent = numOfContent;
                this.maxContent = maxContent;
                this.maxButton = maxButton;
                this.maxPage = Math.ceil(numOfContent / maxContent);
                this.page = 1;
                this.updatePageGroup();
                this.dividedObjects = this.divideObjects(objectTest, maxContent); // objectTest는 외부에서 정의되어야 함

                this.renderPage();
                this.renderList(0);
                this.setupListeners();
            }

            updatePageGroup() {
                this.pageGroup = Math.ceil(this.page / this.maxButton);
                this.pagefirst = ((this.pageGroup - 1) * this.maxButton) + 1;
                this.pagelast = Math.min(this.maxPage, this.pageGroup * this.maxButton);
            }

            setupListeners() {
                document.querySelector("#next").addEventListener("click", this.next.bind(this));
                document.querySelector("#prev").addEventListener("click", this.prev.bind(this));
                document.querySelector("#first").addEventListener("click", this.first.bind(this));
                document.querySelector("#end").addEventListener("click", this.end.bind(this));
                this.render.addEventListener("click", this.handlePageClick.bind(this));
            }

            next() {
                if (this.pagelast < this.maxPage) {
                    this.page = this.pagelast + 1;
                    this.updatePageGroup();
                    this.renderPage();
                    this.renderList(this.pagefirst - 1);
                }
            }

            prev() {
                if (this.page > 1) {
                    this.page = Math.max(1, this.page - this.maxButton);
                    this.updatePageGroup();
                    this.renderPage();
                    this.renderList(this.pagefirst - 1);
                }
            }

            first() {
                this.page = 1;
                this.updatePageGroup();
                this.renderPage();
                this.renderList(this.page - 1);
            }

            end() {
                this.page = this.maxPage;
                this.updatePageGroup();
                this.renderPage();
                this.renderList(this.page - 1);
            }

            handlePageClick(event) {
                const target = event.target;
                if (target.tagName === "BUTTON") {
                    Array.from(this.render.children).forEach(child => {
                        child.classList.remove("active");
                    });

                    target.classList.add("active");
                    const number = parseInt(target.dataset.page, 10) - 1;
                    this.renderList(number);
                }
            }

            renderPage() {
                let html = '';
                let pagesToShow = Math.min(this.maxButton, this.maxPage - this.pagefirst + 1);
                for (let i = this.pagefirst; i < this.pagefirst + pagesToShow; i++) {
                    html += `<button ${i === this.pagefirst ? 'class="active"' : ''} data-page=${i}>${i}</button>`;
                }
                this.render.innerHTML = html;
            }

            divideObjects(objects, batchSize) {
                var dividedObjects = [];
                var currentIndex = 0;

                while (currentIndex < objects.length) {
                    var batch = objects.slice(currentIndex, currentIndex + batchSize);
                    dividedObjects.push(batch);
                    currentIndex += batchSize;
                }

                return dividedObjects;
            }

            renderList(number) {
                let html = '';
                const lists = this.dividedObjects[number] || [];

                for (let i = 0; i < lists.length; i++) {
                    html += `<li><span>${lists[i].list}</span><p>${lists[i].main}</p></li>`; // 여기에 있는 닫는 태그가 올바르게 수정되었습니다.
                }
                this.contents.innerHTML = html;
            }
        }

        // 사용 예:
        const paginator = new Paginator(".contents", ".render", 178, 10, 5);

    </script> -->
</body>

</html>

 

기본적인 페이지네이션을 구현했습니다.