- 오늘 할 것은 패럴랙스 효과입니다.
- 패럴랙스 효과란 페이지를 스크롤 했을 때 현재 보여지는 화면에 해당되는 좌표값을 가져온 다음 좌표값에 따라 이미지에 효과를 주는 방식입니다.
- 그러려면 가장 중요한 것은 기준에 따른 좌표값을 가져오는 것인데 해당 블로그에서는 현재 Y좌표값과 각 사진의 Y좌표값을 구해보았습니다
- 스크립트를 보시죠
<script>
window.addEventListener("scroll", ()=>{
let scrollTop = window.pageYOffset || window.scrollY ||document.documentElement.scrollTop;
//info
document.querySelector(".scroll span").innerHTML = parseInt(scrollTop);
// 좌표값 구해서 입력하기
document.querySelector(".info .offset1").innerText = document.getElementById("section1").offsetTop
document.querySelector(".info .offset2").innerText = document.getElementById("section2").offsetTop
document.querySelector(".info .offset3").innerText = document.getElementById("section3").offsetTop
document.querySelector(".info .offset4").innerText = document.getElementById("section4").offsetTop
document.querySelector(".info .offset5").innerText = document.getElementById("section5").offsetTop
document.querySelector(".info .offset6").innerText = document.getElementById("section6").offsetTop
document.querySelector(".info .offset7").innerText = document.getElementById("section7").offsetTop
document.querySelector(".info .offset8").innerText = document.getElementById("section8").offsetTop
document.querySelector(".info .offset9").innerText = document.getElementById("section9").offsetTop
document.querySelectorAll(".parallax__item").forEach((el, i)=>{
if (scrollTop >= el.offsetTop -2){
document.querySelectorAll(".parallax__nav li").forEach((li)=>{
li.classList.remove("active");
});
document.querySelector(".parallax__nav li:nth-child("+(i+1)+")").classList.add("active");
};
});
document.querySelectorAll(".parallax__nav li a").forEach(li => {
li.addEventListener("click", (e) => {
e.preventDefault();
document.querySelector(li.getAttribute("href")).scrollIntoView({
behavior : "smooth"
})
})
});
})
</script>
- window.addEventListener에 scroll를 주어 스크롤를 했을 때 함수가 실행되게 해주었습니다. 그리고 가장 먼저한 일은 좌표값을 저장한 것입니다.
- 그리고 그걸 .scroll 에 있는 span 태그에 저장해 주었습니다.
- document.querySelector(".info .offset1").innerText = document.getElementById("section1").offsetTop 이건 그 아래에 있는 .info .offset1에 페이지 기준으로 각각 사진들의 Y좌표값을 넣어준 것입니다. getElementById로 선택을 하고 offsetTop으로 위에서 부터의 좌표값을 구했습니다.
- 그렇게 첫번째 사진부터 마지막 사진까지 구해주었죠
- 이부분을 반복문으로 하면 더욱 간단합니다. 여러가지 방법으로 같이 해보시죠
for 문
for(i=1; i<10; i++){
document.querySelector(".info .offset"+i).innerText = document.getElementById("section"+i).offsetTop
}
- 가장 간단한 for문 입니다.
- 9번 반복시켜준다음 i값을 offset 뒤에 붙여주면 끝이납니다.
forEach 문
document.querySelectorAll(".info ul li").forEach((el, i)=>{
document.querySelector(".info .offset"+(i+1)).innerText = document.getElementById("section"+(i+1)).offsetTop
})
- forEach문도 어렵지 않습니다.
- querySelectorAll로 li 를 선택한 뒤 i값은 0부터 시작이니 +1 해서 주면 끝이 납니다.
for in 문
for(let i in document.querySelectorAll(".info ul li")){
document.querySelector(".info .offset"+(parseInt(i)+1)).innerText = document.getElementById("section"+(parseInt(i)+1)).offsetTop;
}
- 여기서 부턴 좀 어렵습니다.
- for in문은 배열의 키 값을 반환 합니다. 배열은 0부터 시작하니 사실상 Index값과 다를 것이 없지만 숫자가 아니라 문자열로 반환이 됩니다.
- parseInt은 문자열을 숫자로 반환해 줍니다. 그렇게 한다면 큰 문제가 없지용
for of 문
for (const [i, el] of document.querySelectorAll(".info ul li span").entries()){
el.innerHTML = document.getElementById("section"+(parseInt(i)+1)).offsetTop;
}
- for of 문은 요소를 가져옵니다. 그렇기 때문에 좌표값을 입력을 해야되는 span태그를 바로 선택해 주었습니다.
- 그래서 선택할 요소 대신에 el 값을 적어주면 됩니다.
- entries()는 객체를 배열형태로 반환해 준다고 생각을 하면 이해하기 쉽습니다. 이걸 씀으로 배열의 키값인 인덱스 값도 구할 수 있는 것이죠
- 그래서 (parseInt(i)+1)를 적어주어서 하면 끝입니다.
document.querySelectorAll(".parallax__item").forEach((el, i)=>{
if (scrollTop >= el.offsetTop -2){
document.querySelectorAll(".parallax__nav li").forEach((li)=>{
li.classList.remove("active");
});
document.querySelector(".parallax__nav li:nth-child("+(i+1)+")").classList.add("active");
};
});
- 이건 해당 좌표에 갔을 때 해당하는 네비게이션 번호에 active를 주는 함수입니다.
- scrollTop >= el.offsetTop -2 // 보고있는 Y좌표의 값이 사진의 offsetTop값보다 크거나 같다면 다른 쪽의 active는 지우고 해당하는 번호에 active를 부여하는 것입니다.
document.querySelectorAll(".parallax__nav li a").forEach(li => {
li.addEventListener("click", (e) => {
e.preventDefault();
document.querySelector(li.getAttribute("href")).scrollIntoView({
behavior : "smooth"
})
})
})
- 이건 네비게이션 번호를 클릭하면 해당하는 사진으로 이동하는 함수입니다.
- 네비게이션의 번호들을 선택해서 forEach문을 쓰는 것이죠
- 요소를 클릭했을 때 함수가 실행됩니다.
- 각 링크(a)에 대해 addEventListener() 메서드를 사용하여 클릭 이벤트 리스너를 추가합니다. 클릭 이벤트가 발생하면, 이벤트 객체(e)의 기본 동작을 중단시키기 위해 e.preventDefault()를 사용하였습니다.
- 그 후, getAttribute() 메서드를 사용하여 클릭된 링크(a)의 href 속성값을 가져와 querySelector() 메서드를 사용하여 해당 id 값을 가진 요소를 선택하였습니다.
- 그리고 부드러운 효과를 주기위해서 behavior : "smooth"를 주었습니다.
- 끝