Vue

Vue | life cycle을 활용하여 scroll event를 적용해보자

반응형

Post 계기

팀프로젝트를 진행하던 도중 페이지의 메뉴바와 검색창을 마우스 스크롤에 따라

숨기거나 드러나게 하는 기능을 구현하기 위해 적용했던 방법을 기록하려고 한다.


구현 기능

- router-link 전환시에 페이지의 위치를 최상단으로 오게한다.

- 마우스 스크롤에 따라 header숨기기도 하고 나타나게도 한다.

구현 방식

- Vuelife cyclemounted, unmounted를 활용

- addEventListener를 사용하여 scroll 이벤트를 감지

- classListadd 또는 remove를 통해 CSS 속성 적용


JavaScript Code

mounted

인스턴트 컴포넌트들을 mount한 다음 호출된다.

이 경우에는 window.scrollTo(0, 0) 을 통해 화면전환시 스크롤의 좌표를 0, 0 으로 리셋시킨다.
EventListener에 scroll시 호출한 함수를 추가시킨다.

  // 컴포넌트 인스턴스가 마운트 된 후 호출된다.
  mounted() {
    window.scrollTo(0, 0);
    document.addEventListener('scroll', this.scrollEvents);
  },

unmounted

mounted에서 추가했던 EventListener를 제거해 주는 작업을 진행한다.

이 부분을 생략한다면 router-link를 통해 화면을 전환하여도 메모리에서는 여전히 동작하기 때문에
다른 method들과 충돌이 발생할 수도 있다.

  // 컴포넌트 인스턴스가 마운트 해체된후 호출된다.
  unmounted() {
    document.removeEventListener('scroll', this.scrollEvents);
  },

scrollEvents

페이지마다 또다른 nav가 존재하는 경우가 있다.
그 경우에는 headerState 를 통해 return값을 다르게 받아오기로 하였다.

scrollEvents() {
    const headerState = this.headerState;
    this.headerScrollEvent(headerState);
    // 특정페이지에는 이 부분의 주석을 해제해 준다.
    // this.navScrollEvent();
},
반응형

headerScrollEvent

headerScrollEvent(headerState) {
  // 현재 스크롤 탑
  const beforeScrollTop = this.currentScrollValue;
  // 스크롤 후의 탑
  const afterScrollValue = document.documentElement.scrollTop;
  // page의 헤더
  const pageHeader = document.querySelector('.row1');

  // 추후에 nav가 생기더라도 수정해줄 필요가 없다.
  if (headerState) {
      if (afterScrollValue > beforeScrollTop) {
        pageHeader.classList.add('header_none');
      this.currentScrollValue = beforeScrollTop;
      return
      } else {
        pageHeader.classList.remove('header_none');
        this.currentScrollValue = beforeScrollTop;
        return
      }
  } else {
      if (afterScrollValue > beforeScrollTop) {
        pageHeader.classList.add('header_none');
        this.currentScrollValue = afterScrollValue;
        return
      } else {
        pageHeader.classList.remove('header_none');
        this.currentScrollValue = afterScrollValue;
        return
    }
  }
},

navScrollEvent

navScrollEvent() {
    // 현재 스크롤 탑
    const beforeScrollTop = this.currentScrollValue;
    // 스크롤 후의 탑
    const afterScrollValue = document.documentElement.scrollTop;
    // page의 nav
    const pageNav = document.querySelector('.wrap_company_nav_container');

    if (afterScrollValue > beforeScrollTop) {
        pageNav.classList.add('nav_none');
        this.currentScrollValue = afterScrollValue;
        return
    }
    else {
        pageNav.classList.remove('nav_none');
        this.currentScrollValue = afterScrollValue;
        return 
    }
}

this.currentScrollValue의 return 값이 다른 이유

header를 숨길지 드러낼지 판단하는 부분만 보게되면 currentScrollValue를

스크롤을 후의 값으로 해줘도 문제가 없었다.

 

그러나 currentScrollValue를 스크롤 후의 값으로 해주게 되면 뒤이어 호출되는 nav 부분에서

판단의 근거가 되는 before과 after의 값이 같아지는 현상이 발생했다.

이를 해결하기 위해서 header, nav 두개가 존재하는 경우에는 currentScrollValue를 스크롤 전의 값으로 return 받았다.

 

이 부분을 조금더 효율적으로 할 수 있는 방법이 없을까?

반응형