새해입니다! 2021년이 밝았어요.
다들 새해 복 많이 받으시길 바랍니다! 이글을 읽는 모두 다들 건강하시고 행보쿠하셨으면 좋겠어요 :)
오늘은 7번째 시간이에요! Day 13 project 는 애니메이션이 있는 게시물을 만드는 과제였습니다. 시작해보겠습니다!
scroll
이벤트가 발생함에 따라 게시물의 사진 애니메이션을 구현한다.
난도가 엄청나게 높은건 아니였지만, HTML
속성에 대해서 이해가 약간 필요한 과제였습니다.
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));
먼저 전체적인 코드는 위와 같습니다! 걱정하지마세요! 찬찬히 정리해보려고합니다 :) 함수 하나하나 한번 살펴볼까요!
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
변수에 따라 그 시간마다 한 번 수행하도록 등록합니다.
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
보다 작으면 이미 스크롤이 넘어간 것 입니다.
이렇게 이해할 수 있겠죠!
따라서 두개의 변수, isHalfShown
과 isNotScrolledPast
로 이미지를 보여줄건지, 숨길건지에 대한 판단을 합니다.
if (isHalfShown && isNotScrolledPast) {
sliderImage.classList.add('active');
} else {
sliderImage.classList.remove('active');
}
}
이 부분은 간단하죠 :)
약간 이번 과제는 HTML
요소가 가미되어 헷갈렸던 과제였던 것 같아요. 그래서 저도 이해하기 위해서 아이패드로 그림을 그려봤고, 그 그림들을 첨부해놓았답니다 :)
근데 혼자 이런 생각을 할 수 있을런지 모르겠어요.. 익숙해져야죠!
밖에 눈이 오네요! 다들 코로나 조심하시고, 새해 복 많이 받으시고요!
틀린내용이나 수정할 내용이 있다면 언제든지 피드백 부탁드립니다!
감사합니다!🤗