본문 바로가기

개발/JavaScript 30

13. Slide in on Scroll

반응형

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>

  <div class="site-wrap">
    <h1>Slide in on Scroll</h1>
  </div>

  <script>
    function debounce(func, wait = 20, immediate = true) {
      var timeout;
      return function() {
        var context = this, args = arguments;
        var later = function() {
          timeout = null;
          if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
      };
    }

  </script>

  <style>
    html {
      box-sizing: border-box;
      background:#ffc600;
      font-family:'helvetica neue';
      font-size: 20px;
      font-weight: 200;
    }
    body {
      margin: 0;
    }
    *, *:before, *:after {
      box-sizing: inherit;
    }

    h1 {
      margin-top: 0;
    }

    .site-wrap {
      max-width: 700px;
      margin: 100px auto;
      background:white;
      padding:40px;
      text-align: justify;
    }

    .align-left {
      float:left;
      margin-right:20px;
    }

    .align-right {
      float:right;
      margin-left:20px;
    }

    .slide-in {
      opacity:0;
      transition:all .5s;
    }

    .align-left.slide-in {
      transform:translateX(-30%) scale(0.95);
    }
    .align-right.slide-in {
      transform:translateX(30%) scale(0.95);
    }

    .slide-in.active {
      opacity:1;
      transform:translateX(0%) scale(1);
    }

  </style>

</body>
</html>

목표

그림들이 스크롤을 올렸다 내렸다 할 때 각 사이드에서 나타나도록 만든다.

코드 분석

  const sliderImages = document.querySelectorAll('.slide-in');

  function checkSlide(e) {
    sliderImages.forEach(sliderImage => {
      const slideInAt = (window.scrollY + window.innerHeight) -
      sliderImage.height / 2;
      const imageBottom = sliderImage.offsetTop + sliderImage.height;
      const isHalfShown = slideInAt > sliderImage.offsetTop;
      const isNotScrolledPast = window.scrollY < imageBottom;
      if (isHalfShown && isNotScrolledPast) {
        sliderImage.classList.add('active');
      } else {
        sliderImage.classList.remove('active');
      }
    });
  }

  window.addEventListener('scroll', debounce(checkSlide));

먼저, 몰랐던 부분만 골라서 체크해보자.
.scrollY는 스크롤을 내릴때 내려간 픽셀 값을 출력하고, .innerHeight는 현재 윈도우 창의 길이 값을 출력한다. 중요한 부분은 현재 윈도우 창이기 때문에 창의 크기에 변화를 주면 이 값 역시 변하게 된다.
.offsetTop은 창의 맨 위에서부터의 길이값을 출력한다.

이제 전체 흐름을 정리해보면,
slideInAt 은 윈도우 기본 창길이와 스크롤 내린 길이를 더한 값에 그림의 길이의 1/2을 빼준 값이다.
imageBottom은 말 그대로 그림의 맨 아래위치 값이다.
if문을 정리하면서 위의 두개를 같이 정리해보겠다.
isHalfShown에 따라 맨 위의 창에서부터 그림까지의 길이가 slideInAt보다 작고, isNotScrolledPast에 따라 그림의 맨 끝의 길이값보다 내가 스크롤을 내린 길이 값이 더 작은 두 조건이 동시에 참일 때, 그림이 나타나도록 정해 놓은 것이다.
마지막으로 위에 있던 debounce는 함수 시행에서 딜레이를 넣어 필요 이상으로 자꾸 이벤트가 발생하지 않도록 해주는 것이다.

마무리

이번 파트도 크게 어려운 부분은 없었지만, 저 값들의 위치값을 생각해보는게 살짝 어려웠다.
끝.

반응형

'개발 > JavaScript 30' 카테고리의 다른 글

15. LocalStorage  (0) 2017.04.22
14. JavaScript References VS Copying  (0) 2017.04.19
12. Key Sequence Detection  (0) 2017.04.18
11. Custom Video Player  (0) 2017.04.18
10. Hold Shift and Checkboxes  (0) 2017.04.14