본문 바로가기
Today I learned

2021 05 04 - 이슈 수정을 위한 infinite scroll 연구

by soheemon 2021. 5. 4.

Infinite Scroll관련 이슈가 하나 올라왔는데.. 개념을 몰라서 코드분석과 원인 파악이 어렵다.

그래서 시작하는 포스팅!

동작 자체는 어렵지 않다.
컨텐츠가 바닥에 닿으면 새로운 컨텐츠를 로딩해서 뒤에 붙여줌!

로직

스크롤 이벤트가 발생할때마다 바닥에 닿았는지 여부를 확인하고!
바닥에 닿으면 컨텐츠 붙여주기!

코드로 가져와보자

- 스크롤이 바닥에 닿았는지 어떻게 판단할것인가.

clientHeight = Element의 내부높이. 화면에 보이는만큼의 높이
offsetHeight = Element의 전체높이
ScrollHeight = Element의 실제 높이. 스크롤해서 내려갈 수 있는 전체 높이이다.
ScrollTop = 스크롤되어 올라간만큼의 높이
scrollY = 윈도우 스크롤Y값
document.documentElement = 문서의 루트요소 루트요소엔 콘텐츠가 전부 들어감.

방법 1)
//pageYOffset = 스크롤의 현재 높이 (얼만큼 깊게 스크롤했는지!)
//document.documentElement = html임 따라서 html 태그의 높이!
var currentHeight = window.pageYOffset + document.documentElement.clientHeight    //화면에 보이는영역 + 스크롤해서 내려간영역 = 사용자가 현재까지 본 영역!
var htmlScrollHeight = document.documentElement.scrollHeight    //html문서 전체 크기!
var triggerEventStatus = currentHeight >= (htmlScrollHeight * 50/100)    //전체 컨텐츠의 50%를 보면 트리거 발생!


방법 2) 
var html = document.documentElement
var triggerEventStatus = (html.scrollHeight - html.scrollTop) <= html.clientHeight;    //(전체 콘텐츠 요소 길이 - 스크롤 한 길이)볼수있는 컨텐츠의 영역 <= 사용자가 보이는 영역 (마지막 볼수있는 영역까지 보면!)

- 스크롤 이벤트가 너무 빈번하게 발생한다.
Throttling : scroll이벤트처럼 빈번하게 발생하는 이벤트를 딜레이 마다 한번씩 실행되게 해준다.

// ES6 code
function throttled(delay, fn) {
  let lastCall = 0;
  return function (...args) {
    const now = (new Date).getTime();
    if (now - lastCall < delay) {
      return;
    }
    lastCall = now;
    return fn(...args);
  }
}

debouncing : 자동완성처럼 - 사용자의 입력에 이벤트가 걸려있을때 주로 사용한다.
이벤트가 발생하고 나서 setTimeout의 딜레이가 지나기전에 새로운 이벤트가 발생하면, 그 이벤트는 무시된다.
setTImeout이 온전히 끝나고 나서야 이벤트가 실행된다.

// ES6
function debounced(delay, fn) {
  let timerId;
  return function (...args) {
    if (timerId) {
      clearTimeout(timerId);
    }
    timerId = setTimeout(() => {
      fn(...args);
      timerId = null;
    }, delay);
  }
}

https://codeburst.io/throttling-and-debouncing-in-javascript-646d076d0a44

남은과제

- DOM렌더링은 생각보다 비싸다.
- 상세페이지 확인후 뒤로가기 했을때 목록을 어떻게 유지할것인가?

참고문서

ko.javascript.info/size-and-scroll-window

댓글