Javascript_30_13

Derek·2021년 1월 1일
1

javascript_30

목록 보기
14/31
post-thumbnail

안녕하세요!

Derek입니다. 😏

새해입니다! 2021년이 밝았어요.
다들 새해 복 많이 받으시길 바랍니다! 이글을 읽는 모두 다들 건강하시고 행보쿠하셨으면 좋겠어요 :)


오늘은 7번째 시간이에요! Day 13 project 는 애니메이션이 있는 게시물을 만드는 과제였습니다. 시작해보겠습니다!




13. Slide in on Scroll

목표

scroll 이벤트가 발생함에 따라 게시물의 사진 애니메이션을 구현한다.

난도가 엄청나게 높은건 아니였지만, HTML 속성에 대해서 이해가 약간 필요한 과제였습니다.




Derek 과 Wes Bos 의 구현코드

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);
      };
    }

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

    const checkSlide = (e) => {
      console.log(window.scrollY, window.innerHeight)
      sliderImages.forEach(sliderImage => {
        // half way through the image
        const slideInAt = (window.scrollY + window.innerHeight) - (sliderImage.height / 2);
        
        // the location of image bottom in the window
        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));

먼저 전체적인 코드는 위와 같습니다! 걱정하지마세요! 찬찬히 정리해보려고합니다 :) 함수 하나하나 한번 살펴볼까요!


1. debounce 함수

처음 들어보는 함수였습니다! debounce 함수의 뜻부터 알아보면,

Debounce는 여러 개의 순차적 호출을 하나의 그룹으로 그룹화할 수 있습니다.

라고 합니다. 즉, 발생하는 이벤트를 일정시간 묶음으로 묶어 하나로 취급하는 형태인것 같아요.

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);
      };
    }

해당 함수는 제공받은 함수입니다. 한줄한줄에 대한 설명은 여기에서 참고하면 될것 같아요.

javascript 30 에서는 이 함수를 제공하여 제가 원하는 스크롤 함수를 debounce 형태로 등록하는 형식이였습니다.

즉, 모든 scroll 마다 원하는 이벤트가 아니라, 설정한 시간인 wait 변수에 따라 그 시간마다 한 번 수행하도록 등록합니다.

2. checkSlide 함수

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

const checkSlide = (e) => {
      sliderImages.forEach(sliderImage => {
        // half way through the image
        const slideInAt = (window.scrollY + window.innerHeight) - (sliderImage.height / 2);
        const isHalfShown = slideInAt > sliderImage.offsetTop;
        
        // the location of image bottom in the window
        const imageBottom = sliderImage.offsetTop + sliderImage.height;
        const isNotScrolledPast = window.scrollY < imageBottom;
        
        if (isHalfShown && isNotScrolledPast) {
          sliderImage.classList.add('active');
        } else {
          sliderImage.classList.remove('active');
        }
      });
    }

checkSlide 함수는 debounce 로 등록하여 window element 에 등록했습니다.

checkSlide 함수는 sliderImages 라는 elements에 대해서 익명함수를 수행해요.

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

sliderImages 객체들은 이미지들! 이라고 생각하셔도 무방할 것 같습니다 :)

slideInAt 변수는, 다음 기능을 구현할때 사용돼요.

이미지는 처음에 비어있지만, 스크롤하다 빈 이미지의 반을 넘어가면 이미지는 표시한다.

따라서, 해당 기능을 위해서, 다음의 변수를 사용해요

  • window.scrollY : 내가 얼마나 스크롤 했는지
  • window.innerHeight : 켜진 인터넷 창의 높이
  • sliderImage.height : 각각 이미지의 높이

slideInAt 변수와 sliderImage.offsetTop 을 비교하여 부울형 변수인 isHalfShown 을 만들고, 이 친구를 판단의 척도로 사용합니다. 즉,

  • slideInAt > sliderImage.offsetTop : 이미지 반이 창에 떴다. 이미지를 보여주자!
  • slideInAt < sliderImage.offsetTop : 이미지가 아직 조오기 밑에 있다.

이런식으로요!

또한, imageBottom 변수는 스크롤이 다 되어 이미지를 지나가면 이미지를 다시 숨기기 위한 플래그입니다. imageBottom 은 각각 이미지의 바닥이 전체 창에서 어느 위치에 있는지에 대한 변수며, 그 값이 스크롤 값인 window.scrollY 를 넘으면 아직 거기까지 스크롤이 안된것이며, 반대로 window.scrollY 보다 작으면 이미 스크롤이 넘어간 것 입니다.
이렇게 이해할 수 있겠죠!

따라서 두개의 변수, isHalfShownisNotScrolledPast 로 이미지를 보여줄건지, 숨길건지에 대한 판단을 합니다.

if (isHalfShown && isNotScrolledPast) {
          sliderImage.classList.add('active');
        } else {
          sliderImage.classList.remove('active');
        }
}

이 부분은 간단하죠 :)




약간 이번 과제는 HTML 요소가 가미되어 헷갈렸던 과제였던 것 같아요. 그래서 저도 이해하기 위해서 아이패드로 그림을 그려봤고, 그 그림들을 첨부해놓았답니다 :)

근데 혼자 이런 생각을 할 수 있을런지 모르겠어요.. 익숙해져야죠!

밖에 눈이 오네요! 다들 코로나 조심하시고, 새해 복 많이 받으시고요!

틀린내용이나 수정할 내용이 있다면 언제든지 피드백 부탁드립니다!
감사합니다!🤗

profile
Whereof one cannot speak, thereof one must be silent.

0개의 댓글