본문 바로가기

기록/수업정리_javascr

scrollTo()

window.scrollTo({ }) : window 객체의 scrollTo, scrollBy 메서드를 사용하여 특정 엘리먼트가 아닌 위치를 기준으로 이동시킨다. window.scrollTo(X, Y) 는 왼쪽 상단을 기준(절대위치)으로 하여 스크롤을 이동시키며, window.scrollBy

좌표값을 사용하여 특정 영역으로 이동하는것이다. 

 

climb-up:^ 한단계 위로 올라가는 속성

<body>
    div#wrap>header#header+main#container>section.sec#section$*4^footer
</body>

위와 같이 푸터가 메인에서 빠져나와 있는걸을 알수 있다.

<body>
    <div id="wrap">
        <header id="header">
            <h1 class="logo">
                <a href="#">logo</a>
            </h1>
            <nav class="nav">
                <ul class="gnb">
                    <li><a href="#section1">MENU 1</a></li>
                    <li><a href="#section2">MENU 2</a></li>
                    <li><a href="#section3">MENU 3</a></li>
                    <li><a href="#section4">MENU 4</a></li>
                </ul>
            </nav>
        </header>
        <main id="container">
            <section class="sec" id="section1">
                <h2>SECTION1</h2>
            </section>
            <section class="sec" id="section2">
                <h2>SECTION2</h2>
            </section>
            <section class="sec" id="section3">
                <h2>SECTION3</h2>
            </section>
            <section class="sec" id="section4">
                <h2>SECTION4</h2>
            </section>
        </main>
        <footer id="footer"></footer>
    </div>

html을 사용해서 원하는 위치로 메뉴를 누르면 이동할 수도 있지만 부드럽게는 되지 않는다 이럴때 자바를 사용해 주어야한다.

위와 같이 보이게 되는데 여기서 내가 보는 sec2는 위에 sec1이 브라우저 밖으로 나가 있고 아래로는 3,4 가 나가 있다 즉 스크롤에 따라 내가 보는 영역이 정해지는것이다. 그렇기 때문에 부드럽게 하기 위해서는 스크롤의 좌표값을 특정하여 알아내야 한다.

                    <li><a href="#section1" class="link">MENU 1</a></li>
                    <li><a href="#section2" class="link">MENU 2</a></li>
                    <li><a href="#section3" class="link">MENU 3</a></li>
                    <li><a href="#section4" class="link">MENU 4</a></li>

각 gnb에 a태그를 걸어주고 같은 클래스를 넣어 함께 잡을수 있도록 한다.

    <script>
        let btnLink=document.querySelectorAll(".link");
        console.log(btnLink);
        btnLink[1].addEventListener("click", function(e){//a태그로 이동하는데 특정 영역으로 이동시키는걸 막기 위해서 하나를 선언
            e.preventDefault();
            window.scrollTo({top: 1000, behavior:"smooth"});//행동을 부드럽게 한다는 의미
        })
    </script>

selectAll로 다같이 잡아주고 변수로 선언해준다. 그리고 두번째에 해당하는 버튼에 적용되도록 [1]로 인덱스 번호를 지정하여서 클릭되는 개별의 변수에게 e 라고 선언을 해주고 e에게 스크롤을 지정해준다. top으로 스크롤 위치를 지정해주고 행동을 부드럽게 설정해주면 해당 버튼을 누르게 되면 해당 스크롤로 부드럽게 움직이게 된다.

 

Event.preventDefault() 는 a 태그나 submit 태그는 누르게 되면 href 를 통해 이동하거나 , 창이 새로고침하여 실행됩니다.

preventDefault 를 통해 이러한 동작을 막아줄 수 있다. 그렇기 때문에 이를 지정해야 새로운 창이 열리지 않고 부드럽게 움직이게 되는것이다. 그렇기 때문에 꼭 넣어주어야 한다.

    <script>
        let btnLink=document.querySelectorAll(".link");
        console.log(btnLink);
        btnLink[0].addEventListener("click", function(e){
            e.preventDefault();
            window.scrollTo({top: 0, behavior:"smooth"});
        })
        btnLink[1].addEventListener("click", function(e){//a태그로 이동하는데 특정 영역으로 이동시키는걸 막기 위해서 하나를 선언
            e.preventDefault();
            window.scrollTo({top: 1000, behavior:"smooth"});//행동을 부드럽게 한다는 의미
        })
        btnLink[2].addEventListener("click", function(e){
            e.preventDefault();
            window.scrollTo({top: 2000, behavior:"smooth"});
        })
        btnLink[3].addEventListener("click", function(e){
            e.preventDefault();
            window.scrollTo({top: 3000, behavior:"smooth"});
        })
    </script>

 

각각의 스크롤의 좌표를 지정하여 버튼마다 지정하여 넣어주면 해당 위치로 이동하게 된다.


        let btnLink=document.querySelectorAll(".link");
       
        btnLink.forEach(function(link){
            link.addEventListener("click", function(e){
                e.preventDefault();
                window.scrollTo({top: , behavior:"smooth"});
            });
        });

forEach를 사용해서 적용할 수도 있는데 여기서는 연산식을 넣어주어야 한다. 이전의 식에서 1000씩 값이 올라갔었는데 식으로 풀게 되면 1000에 인덱스번호의 숫자만큼 곱해주는것이 된다. 이를 산술연산자로 풀게 되면

이런식으로 된다 즉 인덱스 번호를 선언하고 top값에 1000*idx(인덱스 번호)를 넣어 계산식이 적용되도록 하면 자동으로 지정되거 이동되는것을 확인할 수 있다.


이전에는 값을 1000px로 지정하였는데 이번에는 자동으로 높이값을 파악하여 넣도록 단위를 vh로 바꾸어주고 자바에도 이를 적용하도록 하여 스크립트를 수정하지 않도록 하고 싶다.

    <script>
        let btnLink=document.querySelectorAll(".link");
        let secH=document.querySelector("#section1").offsetHeight; //sec1의 높이값을 찾아서 secH에 저장하라는 명령어
        console.log(secH)

자동으로 높이값을 찾아 계산해 변수에 넣어주고 해당값을 top에 넣어서 값이 계산되도록 한다.

    <script>
        let btnLink=document.querySelectorAll(".link");
        let secH=document.querySelector("#section1").offsetHeight; //sec1의 높이값을 찾아서 secH에 저장하라는 명령어
        console.log(secH)
       
        btnLink.forEach(function(link, idx){
            link.addEventListener("click", function(e){
                e.preventDefault();
                window.scrollTo({top: secH*idx, behavior:"smooth"});
            });
        });
       
    </script>

 

이것의 단점도 있는데 vh로 지정해놓았기 때문에 이를 실행할때 그때의 높이값을 계산한다. 근데 이후 브라우저의 크기를 달리하면 위치가 맞지 않게 된다. 처음의 값만을 지정하고 있기 때문이다. 이때 하나의 식을 더 추가해주는데.

        window.addEventListener("resize", function(){ })

 

"resize" 이다. 이는 윈도우 크기를 조정할때 스크립트를 실행시키는 이벤트로 반응형에서 많이 쓰인다.

그리고 변수값을 재할당하여 윈도우 사이즈가 변경될때마다 #section1의 높이값을 파악하여 변수 secH값을 변경한다.

변수를 재할당하여 값이 재설정되도록 하였기 때문에 식에 자동으로 변한 값이 들어가서 브라우저의 크기가 달라져도 자동으로 계산되서 높이를 지정해 바뀌게 된다.

 
    <script>
        let btnLink=document.querySelectorAll(".link");
        let secH=document.querySelector("#section1").offsetHeight; //sec1의 높이값을 찾아서 secH에 저장하라는 명령어
        // console.log(secH)
        window.addEventListener("resize", function(){
            secH=document.querySelector("#section1").offsetHeight;
            console.log(secH)
        })
       
        btnLink.forEach(function(link, idx){
            link.addEventListener("click", function(e){
                // secH=document.querySelector("#section1").offsetHeight;
                e.preventDefault();
                window.scrollTo({top: secH*idx, behavior:"smooth"});
            });
        });
       
    </script>

'기록 > 수업정리_javascr' 카테고리의 다른 글

내장객체 (날짜정보)  (0) 2024.08.02
연산자(증감, 논리)  (0) 2024.08.01
FixedNavigation, 상대좌표값, 절대좌표값  (0) 2024.07.29
javascript_4_함수  (0) 2024.07.18
javascript_3  (0) 2024.07.17
댓글