반응형

0. 목적

-. 코인관련 커뮤니티 글 크롤링 + 네이버뉴스/구글뉴스 검색하는 것 까지는 추가했는데... 한번에 모든 글 혹은 뉴스 기사를 보여주자니 트래픽 소모가 너무 크고, 그에따라 페이지에서 처리시간이 너무 오래걸린다. 이걸 해결하려면, 일정 수량의 글만 보여주는 페이징을 추가해야 하는데, 아무래도 버튼울 누르는 방식으로 페이징 처리 하는 것 보다는 스크롤을 슉슉 내리는 방식으로 구성하는게 목적 (최근 소식들 보기)에 맞는 것 같다는 생각이 든다.

-. 그래서 infinite scroll을 구현해봐야겠다.

-. 어떻게 할까... 를 찾아보니 vue-infinite-loading 이라는 플러그인이 있던데, 이것보단 직접 만드는 것을 택함.

-. 화면 최하단을 인식하고 → 최하단에서 추가 글들을 불러오는 (axios) 방법을 적용하면 될 것 같다. 다행히 스택 오버플로우에 비슷한 질문글이 있다.

1. 스크롤 위치 찾기

-. 화면의 최하단이라는건, 바꿔말하면 스크롤 바가 가장 밑까지 내려갔다는 것이니 스크롤 하단의 위치를 찾아내면 된다. 특이하게도 javascript에 scrollTop은 있는데, scrollBottom은 없더라. 결국 스크롤 최상단 위치 (document.documentElement.scrollTop)와 스크롤바의 길이(창 길이, window.innerHeight)를 더하는 방식으로 구해야 한다.

let scrollBottom = document.documentElement.scrollTop + window.innerHeight

-. 콘솔창에서 테스트를 해봤다.

2. 스크롤 하단 위치 인식

-. 스크롤 하단 위치를 찾게되면, 이제 화면 하단을 인식하는건 어렵지 않다. 나는 200 px정도 버퍼를 두고 먼저 인식하게 (하단 근처로 가면 다음 페이지를 불러오도록) 구성했다.

      let isBottom = (document.documentElement.scrollTop + window.innerHeight + 200 > document.documentElement.offsetHeight);

-. 이제 scroll에 대해 event listener를 설정해서 해당 리스너가 발동될 때 마다 화면 하단인지 여부를 확인하게 하면 된다.

  mounted () {
        window.addEventListener('scroll', this.checkBottom);
  },
  methods: {
    checkBottom (event) {
      let isBottom = (document.documentElement.scrollTop + window.innerHeight + 200 > document.documentElement.offsetHeight);
      console.log('handle')
    },
}

-. 인식은 정상적으로 되는데, 막상 코드를 적용해보면 문제가 있다. 아래 영상을 보면 바로 알 수 있는데, 스크롤이 이동할 때 마다 무한정 리스너가 실행된다. 리소스를 엄청 잡아먹는다는 얘기, 그리고 axios 발동 시 서버에 콜을 엄청 많이 넣는다는 얘기...

3. 리스너 발동 주기 설정

-. 자바스크립트 라이브러리 중에 lodash라고 꽤 유용한 것들을 모아둔 (마치 C의 stdio 처럼...) 것이 있는데, 다행히 뷰cli에서도 쓸 수 있다. 해당 라이브러리의 throttle 함수를 사용한다. 대강 2초 주기로 발동되게 하자.

  mounted () {
        this.handleScroll = lodash.throttle(this.checkBottom, 2000)
        window.addEventListener('scroll', this.handleScroll);
  },
  methods: {
    checkBottom (event) {
      let isBottom = (document.documentElement.scrollTop + window.innerHeight + 200 > document.documentElement.offsetHeight);
      console.log('handle')
    },
}

-. 이제 아까처럼 수십개의 리스너가 발생하지 않고, 적당히 (2초마다) 발생하는 것을 확인할 수 있다.

4. 적용하기

-. 필요한기능들을 모두 확인했으니.. 이제 실제 적용을 해봤다. 

  mounted () {
        this.handleScroll = lodash.throttle(this.checkBottom, 2000)
        window.addEventListener('scroll', this.handleScroll);
  },
  methods: {
    checkBottom (event) {
      let isBottom = (document.documentElement.scrollTop + window.innerHeight + 200 > document.documentElement.offsetHeight);
      console.log('handle')
      if(isBottom){
        console.log('bottom')
      }
    },
}

-. 의도한 대로 (최적인진 모르겠지만) 잘 적용되는 것이 확인된다.

 

728x90
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기