바닥 감지는 다음 코드로 간단하다.
//스크롤 바닥 감지
window.onscroll = function(e) {
//window height + window scrollY 값이 document height보다 클 경우,
if((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
}
};
나머지는 서버에서 페이징 처리된 데이텨 값을 가져와서 파싱후 append 로 붙여주면 된다.
무한 스크롤 처리에서 중요한 부분은
1. 마지막 페이지 인지 확인
서버에서 계산된 마지막 페이지 번호가 자사스크립트에서 현재 페이지 변수 currentPageNo 보다 작을 경우
append 로 중단처리해야 한다.
2.자바스크립트 이벤트 액션값 초기화
append 로 붙여 준후에 추가적으로 자바스크립트 이벤트 액션값을 다시 호출해서 붙여 주는 데,
예 ) like.init();
이 때 반드시 초기화 해야 중복된 자바스크립트 이벤트값이 들어가서 오류가 발생하는 것을 막을 수 있다.
초기화 방법은 다음과 같이 간단하다.
off("click")
$(".like-icon").off("click");
$(".like-icon").on("click", function (e) {
like.likeAction(this);
});
3. 클릭후 상세페이지 보고 나서 이전페이지로 되돌아 갈때 현재 스크롤된 페이지 유지
vue 나 react 의 싱글페이지 어플리케이션 프론트 인 SPA 인경우 에는 문제 되지 않지만,
예를 들어 한페이당 10개 데이터로 10페이지까지 무한 스크롤로 표시 될 경우 맨 하단에에는 100개 표시 될 것이다.
이 때 맨하단에 데이터를 클릭후 되돌아기 버튼을 하면 최상단으로 옮겨지는 이것을 방지 하기위해 는 쿠키값이나
클라이언튼 세션 에 데이터를 저장해야 될 것이다.
다음 을 참조
https://macaronics.net/index.php/m04/jquery/view/1752
https://velog.io/@eunoia/무한-스크롤Infinite-scroll-구현하기
4. 모바일경우에는 바닥 값이 인식이 안될 경우 다음을 참조
https://macaronics.net/index.php/m04/jquery/view/1752
참조 예)
let currentPageNo=1;
infinityScroll={
init:function(){
this.getList();
//스크롤 바닥 감지
window.onscroll = function(e) {
//window height + window scrollY 값이 document height보다 클 경우,
if((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
infinityScroll.getList(currentPageNo);
}
};
},
getList:function(pageIndex){
if(pageIndex==null || pageIndex==undefined || pageIndex==""){
pageIndex=1;
}
const menuActive = $("#menuActive").val();
const param={
'pageIndex':pageIndex,
'menuActive':menuActive
}
$.ajax({
url:'/portal/infiniteScroll.do',
type:'post',
contentType:'application/json;charset=UTF-8',
data:JSON.stringify(param),
dataType:"json",
success:function(res){
//res=JSON.parse(res);
//console.log(res);
//**** 서버에서 계산된 마지막 페이지 번호가 자사스크립트 currentPageNo 작을 경우 중단처리
if(currentPageNo >res.paginationInfo.lastPageNo)return;
console.log(" currentPageNo {} - {}",res.paginationInfo.lastPageNo , currentPageNo , res.paginationInfo.currentPageNo);
currentPageNo++;
let html="";
res.resultList.forEach(function(result){
let likeActive="";
if(result.likeCnt!="0"){
likeActive='like-active';
}
html +=`
<div class="col-lg-4 col-sm-6 mb-4">
<div class="portfolio-item">
<a class="portfolio-link" data-bs-toggle="modal" href="#portfolioModal1" data-nttId="${result.nttId}">
<div class="portfolio-hover">
<div class="portfolio-hover-content"><i class="fas fa-plus fa-3x"></i></div>
</div>
<img class="img-fluid"
src='/cmm/fms/getImage.do?atchFileId=${result.atchFileId}&fileSn=0"/>'
alt="${result.frstRegisterNm}" />
</a>
<div class="portfolio-caption">
<div class="portfolio-caption-heading">
<c:out value="${result.nttSj}" />
</div>
<div class="portfolio-caption-subheading text-muted">
<div class="row">
<div class="col-md-12">
<span class="me-2 news-date"
data-bs-toggle="tooltip" data-bs-placement="top" title="등록일" >
<i class="fa fa-calendar" ></i>
<span>${result.frstRegisterPnttm}</span>
</span>
<span class="me-2 news-like like-icon ${likeActive}" data-nttId="${result.nttId}"
data-bs-toggle="tooltip" data-bs-placement="top" title="좋아요" >
<i class="fa fa-heart heart" ></i>
<span>
${result.likeTotCnt}
</span>
</span>
<span class="me-2 news-views"
data-bs-toggle="tooltip" data-bs-placement="top" title="조회수" >
<i class="fa fa-eye"></i>
<span>${result.inqireCo}</span>
</span>
<span class="me-2 news-comments"
data-bs-toggle="tooltip" data-bs-placement="top" title="댓글수" >
<i class="fa fa-comments" id="fa-comments"></i>
<span>${result.commentTotCnt}</span>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
`;
});//forEach
if(res.resultCnt==0){//전체 게시물 갯수가 0이면
html=`
<div class="col-lg-12 col-sm-12 mb-12 text-center" >
<h5>등록된 데이터가 없습니다.</h5>
</div>
`;
}
$("#contentList").append(html);
//이벤트 처리값을 호출해서 붙여 준다
// 이때 .off("click"); 이벤트 초기화
like.init();
modalAction.init();
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl)
})
},
error:function(res){
console.log("error");
console.log(res);
}
});
}
}
infinityScroll.init();
let like={
init:function(){
$(".like-icon").off("click");
$(".like-icon").on("click", function (e) {
like.likeAction(this);
});
},
likeAction:function(e){
console.log("likeAction ->");
console.log(e);
const nttId =$(e).attr("data-nttId");
console.log(nttId);
const param={
'nttId':nttId
}
$.ajax({
url:'/portal/like/likeAction.do',
type:'post',
contentType:'application/json;charset=UTF-8',
data:JSON.stringify(param),
success:function(res){
//console.log(res);
$(e).removeClass("like-active");
let cnt=$(e).children("span").text();
//console.log("0좋아요갯수:"+ cnt);
cnt=cnt.replace(/\n/g, "");
cnt=cnt.replace(/\s*/g, "");
cnt=Number(cnt);
cnt=parseInt(cnt);
if(res=="1"){
$(e).addClass("like-active");
cnt++;
tInfo("좋아요!","");
}else{
tWarning("좋아요 취소!");
cnt--;
$(e).removeClass("like-active");
}
$(e).children("span").text(cnt);
},
error:function(res){
/* console.log("error");
console.log(res);*/
}
});
}
}
like.init();
























댓글 ( 4)
댓글 남기기