새소식

PHP/PHP

PHP - jquery를 이용한 스크롤 페이징

  • -

스크롤 페이징 처리

  1. 특정 div의 스크롤 이벤트를 감지하여 해당 div의 스크롤 위치가 최하단에 도달할 경우 데이터를 추가로 가져오는 스크롤 페이징 처리

컨트롤러

<?php class ScrollPaging
{
    // 데이터를 가져오는 프로세스
    public function get_data_process()
    {
        header('Content-type: application/json; charset=utf-8');
        $params = $this->vars['params'];

        // 한 페이지에 출력될 데이터 개수
        $result['pagePerEntries'] = 20;
        // 모든 데이터의 개수 (총 개수를 구해서 최대가 몇 페이지인지 알아내기 위함)
        $result['totalEntries'] = $this->model->getFunction($where, 'count');
        // $this->pagination->navy($totalEntries(해당 데이터의 총 개수), $page(몇 페이지의 데이터를 가져와야 하는지), $pagePerEntries = 20(한 페이지당 출력될 데이터 개수))
        $result['pagination'] = $this->pagination->navy($result['totalEntries'], $params['page'], $result['pagePerEntries']);

        $result['data_list'] = [];
        // 데이터가 존재한다면
        if ($result['totalEntries'] > 0) {
            // sql 문법으로 limit에 offset[예)1번째부터 10번째 데이터를 가져오겠다(1, 10)]을 넣어서 해당되는 값을 가져오는 방식
            $result['data_list'] = $this->model->getFunction($where, $result['pagination']['Offset']);
        }

        echo json_encode($result);
        exit;
    }
}
?>

js

var offsetCnt = 0;
var page = 1;
var scroll_active = true;

// 현재 페이지 값에 해당되는 데이터 배열을 받아와 html 형식에 맞춰 출력
function getDataFunction() {
    var params = {
        'page': page
    };

    $.ajax({
        type: "POST",
        data: params,
        dataType: "json",
        url: "/get_data_process",
        success: function (result) {
            // 가져온 데이터로 html 생성
            createTagHtml(result);
        },
        error: function (request, status, error) {
            // 에러 출력
            console.error("code:" + request.status + "\n" + "message:" + request.responseText + "\n" + "error:" + error + "\n" + "request:" + request);
        },
        beforeSend: function () {
            scroll_active = false;
            $('html').css("cursor", "wait");
        },
        complete: function () {
            $('html').css("cursor", "auto");
        }
    });
}

function createTagHtml(result) {
    var data_list = result.data_list;

    // 가져온 데이터를 html 형식에 맞춰 append를 이용해 페이지에 추가해준다.
    var html = '';

    if (data_list.length > 0) {
        // 데이터가 있을 경우
        data_list.forEach((data) => {
            html += `<div>${data}</div>`;
        });
        offsetCnt += data_list.length;

        if (result.totalEntries <= offsetCnt) {
            scroll_active = false;
        } else {
            scroll_active = true;
        }
        $('.tag').append(html);
    } else {
        // 데이터가 없을 경우
        scroll_active = false;
        $('.no_data').show();
        $('.tag').hide();
    }
}


window.onpageshow = function (event) {
    // 페이지 이동 감지 시 스크롤 페이징 데이터 저장
    $(window).on('beforeunload', function () {
        history.replaceState({
            scrollList: $('.tag').html(),
            scroll_active: scroll_active,
            page: page
        }, null);
        $.cookie("scroll_position", $(window).scrollTop(), 1);
    });

    // 스크롤 이벤트를 감지하여 스크롤이 최하단에 도달했을 경우 조건에 따라 데이터 가져오는 함수 실행
    var tag = document.getElementsByClassName('tag')[0];
    tag.addEventListener('scroll', (function () {
        var scrollTop = tag.pageYOffset || tag.scrollTop;

        if (scroll_active && scrollTop != 0) {
            var scroll = scrollTop + tag.offsetHeight; // 최하단에 도달하기 전에 데이터를 불러오려면 +200 (div 크기에 따라 적절하게 +값 조정  ** +값이 너무 크면 한 번에 같은 데이터를 여러 번 가져오게 될 수 있고 데이터를 계속 가져오는 오류가 발생할 수 있음 **)
            var height = tag.scrollHeight;
            if (scroll >= height) {
                page++;
                getDataFunction();
                scroll_active = false;
            }
        }
    }));

    if (event.persisted || (window.performance && window.performance.navigation.type == 2)) {
        // 페이지 로드 시 뒤로가기 이벤트 감지하여 이전 데이터 출력 & 스크롤 이동
        var data = history.state;

        if (data) {
            data.scrolllist = data.scrolllist.replace(/undefined/gi, "");
            $('.tag').html(data.scrolllist);
            var scrollPosition = $.cookie("scroll_position");
            if (scrollPosition != "" && scrollPosition != undefined) {
                $('.tag').scrollTop(scrollPosition);
            }
            scroll_active = data.scroll_active;
            page = data.page;
        }
    } else {
        // 뒤로가기 이벤트로 인한 페이지 로드가 아닐 시 데이터 가져오는 함수 실행
        getDataFunction();
    }
}

html

<!-- html이 추가 될 태그 -->
<div class="tag"></div>
<!-- 데이터가 없을 때 출력되는 태그 -->
<div class="no_data" hidden></div>


<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.