기초부터 시작하는 코딩/Javascript

Javascript를 이용한 사이트 만들기! - 패럴랙스 효과사이트 만들기01

kebab00 2023. 4. 18. 20:04

728x90

- 오늘 할 것은 패럴랙스 효과입니다.

- 패럴랙스 효과란 페이지를 스크롤 했을 때 현재 보여지는 화면에 해당되는 좌표값을 가져온 다음 좌표값에 따라 이미지에 효과를 주는 방식입니다.

- 그러려면 가장 중요한 것은 기준에 따른 좌표값을 가져오는 것인데 해당 블로그에서는 현재 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"를 주었습니다.

- 끝