본문 바로가기
SPRING/SPRING 프로젝트

SPRING 프로젝트 - 펀딩 사이트(7) : 페이지네이션 없이 무한스크롤 구현

by 스노위13 2022. 9. 8.

1. 내용 :  내가 찜한 펀딩을 확인할 수 있는 페이지이다. 찜을 하면 DB에 있는 mem_like에 회원 아이디와 펀딩 번호가 저장되는데 나의 펀딩 페이지에서는 이 mem_like와 funding 테이블을 join해서 데이터를 가져온다. 페이지가 켜지면 바로 ajax를 이용해서 모든 정보를 List로 가지고 오는데 스크롤을 내릴 때마다 12개씩 뜨도록 무한스크롤을 사용하였다.

2. 과정 중 특이점 :  페이지네이션을 사용하면 쉽게 할 수 있지만 데이터를 모두 가져온 다음 필요한만큼 잘라서 무한스크롤을 하고 싶어서 이런 식으로 만들었는데 순서 부분 때문에 좀 헷갈렸다. 선생님의 도움과 구글링으로 해결할 수 있었다. 

3. 화면 및 코드

1) 나의 펀딩 화면

펀딩리스트와 똑같은 모양이다. 아래 영상을 보면 화면을 내리다보면 오른쪽의 스크롤의 크기가 바뀌면서 데이터가 새로 추가되는 것을 확인할 수 있다. 현재는 찜한 데이터가 36개라서 2번 추가되는데 데이터가 더 많으면 계속해서 스크롤이 추가된다. 

2) JSP(전체 코드는 아래의 더보기를 찾아 눌러주세요)

<div class="container" id="list">
</div>

ajax로 받아온 데이터를 넣기 위해 id가 list인 div를 선언하였다.

let memId = $("form[name='fundinginfo']").find('#memId').val();
let list ="";
var result =[];
let currentPage = 0;

$(function(){
	fn_funding_list();
});	

function fn_funding_list(){
	 $.ajax({
       url:"<c:url value='/member/myfundingget.wow'/>"
    	 , data:{memId : memId}
       , success: function(data) {
    	   		console.log(data);
	    	   list = data.result;	    	 
	    	   console.log(list)
	    	   for(i=0; i < list.length; i += 12){
	    	   		result.push(list.slice(i, i + 12));
	    	   }
        },
		error : function() {
            alert('error');
      },
     complete : function() {       
    	 	fn_page(currentPage);
    	  }
	 }); //ajax
}

'나의 펀딩' 화면이 시작되면 데이터를 가지고 오면서 동시에 fn_page가 되어야 하는데 처음 sucess와 error만 있을 때는 fn_page가 실행되지 않았다. 그래서 complete를 사용하여 맨 처음엔 무조건 fn_page가 실행되도록 만들었다. 

fn_page 코드는 아래와 같다. 

function fn_page (num){
	str = "";
	$.each(result[num], function(i, element) {				   
		str+='<div class="funding">';
		str+='<a href="<%=request.getContextPath()%>/funding/fundingView.wow?fuNo='+ element.fuNo +'&memId=${USER_INFO.userId}"><img class="fundingimg" alt="" src="'+ element.fuImg +'"></a>';
		str+='<a href="<%=request.getContextPath()%>/funding/fundingView.wow?fuNo='+ element.fuNo +'&memId=${USER_INFO.userId}"><b>'+ element.fuTitle +'</b></a>';
		str+='<div class="amount">'+ element.fuAmount +' 달성('+ element.fuPercent +' %)</div>';
		str+='<div class="category">♥'+ element.fulike +' <b>|</b> '+ element.fuCate +'	</div>';
		str+='<div class="fuDday"><b>'+ element.fuDday +'일 남음|</b> '+ element.fuSite +' </div>';
		str+='</div>';
	});
		$("#list").append(str);
}

fn_funding_list()에서 받아온 데이터를 스크롤이 바닥에 닿았을 때마다 화면에 띄우도록 만들어져 있다. 스크롤이 바닥에 닿았을 때 인지하는 코드는 아래와 같다.

window.onscroll = function(e) {	
    if((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
    	currentPage +=1;
    	fn_page(currentPage);
    }
};

https://velopert.com/1890

 

[JS] JQuery 를 사용한 무한 스크롤 (Infinite Scroll) 예제 | VELOPERT.LOG

Link: CodePen 생각보다 많이 간단하다 var page = 1; $(window).scroll(function() { if ($(window).scrollTop() == $(document).height() - $(window).height()) { console.log(++page); $("#enters").append(" Page " + page + " So MANY BRS YEAHHH~ So MANY BR

velopert.com

이 코드는 위의 블로그를 참고하여 만들었다! 정말 감사한 곳...ㅠㅠ

전체 코드는 아래 더보기를 눌러주시길~

더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<%@include file="/WEB-INF/inc/header.jsp" %>

<meta charset="UTF-8">
<title>나의 펀딩</title>
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath() %>/resources/css/funding/fundingList.css" />
</head>
<body>
<%@include file="/WEB-INF/inc/top.jsp" %>
<div class="row mt-5"></div>
<form id="fundinginfo" name="fundinginfo" >
<input type="hidden" id="memId" name="memId" value="${USER_INFO.userId }">
</form>
<h1 style="text-align: center; margin-bottom : 20px">나의 펀딩</h1>
<div class="container" id="list">

</div>

<script type="text/javascript">
let memId = $("form[name='fundinginfo']").find('#memId').val();
let list ="";
var result =[];
let currentPage = 0;

function fn_funding_list(){
	 $.ajax({
       url:"<c:url value='/member/myfundingget.wow'/>"
    	 , data:{memId : memId}
       , success: function(data) {
    	   		console.log(data);
	    	   list = data.result;	    	 
	    	   console.log(list)
	    	   for(i=0; i < list.length; i += 12){
	    	   		result.push(list.slice(i, i + 12));
	    	   }
        },
		error : function() {
            alert('error');
      },
     complete : function() {       
    	 	fn_page(currentPage);
    	  }
	 }); //ajax
}

function fn_page (num){
/* 	console.log(result[num]); */
	str = "";
	$.each(result[num], function(i, element) {				   
		str+='<div class="funding">';
		str+='<a href="<%=request.getContextPath()%>/funding/fundingView.wow?fuNo='+ element.fuNo +'&memId=${USER_INFO.userId}"><img class="fundingimg" alt="" src="'+ element.fuImg +'"></a>';
		str+='<a href="<%=request.getContextPath()%>/funding/fundingView.wow?fuNo='+ element.fuNo +'&memId=${USER_INFO.userId}"><b>'+ element.fuTitle +'</b></a>';
		str+='<div class="amount">'+ element.fuAmount +' 달성('+ element.fuPercent +' %)</div>';
		str+='<div class="category">♥'+ element.fulike +' <b>|</b> '+ element.fuCate +'	</div>';
		str+='<div class="fuDday"><b>'+ element.fuDday +'일 남음|</b> '+ element.fuSite +' </div>';
		str+='</div>';
	});
		$("#list").append(str);
}

$(function(){
	fn_funding_list();
});	

//스크롤 바닥 감지
window.onscroll = function(e) {	
    if((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
    	currentPage +=1;
    	fn_page(currentPage);
    }
};

</script>

</body>
</html>

2) Controller

@RequestMapping(value = "member/myfunding.wow")
public String myfunding(Model model) {
    return "member/myfunding";	
}

@RequestMapping(value = "member/myfundingget.wow")
@ResponseBody
public Map<String,Object> myfundingget(String memId) {
    System.out.println("");
    Map<String, Object> map = new HashMap<String, Object>();
    List<FundingVO> myfundingList = likeservice.getLikeList(memId);
    map.put("success", true);
    map.put("result", myfundingList);		
    return map;	
}

myfunding은 처음 주소를 입력했을 때 실행되고, myfundingget은 ajax에서 요청을 보내면 회원의 아이디를 받아 찜한 리스트만 DB에서 가져온 후 보낸다. 찜한 리스트만 DB에서 가져오기 위한 xml은 아래와 같다.

3) xml

<select id="getLikeList" parameterType="String" resultType="com.study.funding.vo.FundingVO">
SELECT    a.fu_no as fu_no        , fu_site
        , fu_title			         , fu_cate        , fu_enter
        , fu_img                  , fu_percent     , fu_amount
        , fu_dday                 , fu_url         , fu_like
FROM    mem_like a , funding b
WHERE  a.fu_no = b.fu_no
	AND mem_id = #{memId}
	ORDER BY like_no
</select>

두 개의 테이블을 조인하여 가지고 온다. 

머릿 속으로 생각한 내용을 구현하는건 어렵지만 참 재밌다는 걸 다시 한 번 느꼈다ㅋㅋㅋ

댓글