Javascript 11장 Back to top 파트 1 / 12장 Back to top 파트 2

김도형·2022년 10월 3일
0

Back to top

로직 드로잉

  • document 움직이고, body는 픽스

css

* {
    box-sizing: border-box;
    -webkit-font-smoothing: antialised;
}

body {
    background-color: #313944;
    padding: 5em 20em;
}

h1 {
	color: #fff;
	font-family: 'Cormorant Infant';
	font-size: 72px;
	font-weight: 700;
	line-height: 72px;
	letter-spacing: -1px;
	margin-bottom: 48px;
	text-align: center;
}

    h1:after {
        color: #1fcfcb;
    	display: block;
    	content: '. . .';
    	font-size: 26px;
    	line-height: 24px;
    	height: 24px;
    	margin: 48px auto;
    }

h2 {
	color: #fff;
	font-family: 'Cormorant Infant';
	font-size: 54px;
	font-weight: 700;
	line-height: 72px;
	letter-spacing: -1px;
	margin-bottom: 48px;
	text-align: center;
}

p {
	color: #bbc8d8;
	font-family: 'Lato';
	font-size: 22px;
	font-weight: 500;
	line-height: 36px;
	margin-bottom: 36px;
	text-align: center;
}

a {
	color: #1fcfcb;
    font-family: 'Lato';
}

    a:hover {
    	color: #fff;
    }

#back-to-top {
    position: fixed;
    bottom: 3em;
    right: 3em;
    background-color: rgba(255, 255, 255, .9);
    color: #313943;
    border: none;
    border-radius: 5px;
    padding: 1em;
    text-transform: uppercase;
    cursor: pointer;
    font-weight: 700;
    box-shadow: 0 0 2em 0 rgba(0, 0, 0, .25);
    transition: all .3s ease-in-out;
    display: inline-block;
    opacity: 0; /* 투명도 0(안보임) */
    text-decoration: none;
    font-size: .75em;
}

    #back-to-top:hover {
        background-color: #fff;
        padding: 1em 3em;
    }

#back-to-top.visible {
    opacity: 1;
}

css에서 id "back-to-top" element에 visible 클래스 네임을 넣으면
opacity : 1 적용 -> top 버튼 보임
#back-to-top.visible {
opacity: 1;
}

순수한 자바스크립트 관리보다 css에서 클래스네임 컨트롤 하는 게 유지보수가 쉽다.

HTML

<header id="top">
            <h1>Moby Dick</h1>
            <h2>by Herman Melville</h2>
        </header>

        <main>
            <p>Presently a breeze sprang up; Stubb feigned to cast off from the whale; hoisting his boats, the Frenchman soon increased his distance, while the Pequod slid in between him and Stubb's whale. Whereupon Stubb quickly pulled to the floating body, and hailing the Pequod to give notice of his intentions, at once proceeded to reap the fruit of his unrighteous cunning. Seizing his sharp boat-spade, he commenced an excavation in the body, a little behind the side fin. You would almost have thought he was digging a cellar there in the sea; and when at length his spade struck against the gaunt ribs, it was like turning up old Roman tiles and pottery buried in fat English loam. His boat's crew were all in high excitement, eagerly helping their chief, and looking as anxious as gold-hunters.</p>

            <p>And all the time numberless fowls were diving, and ducking, and screaming, and yelling, and fighting around them. Stubb was beginning to look disappointed, especially as the horrible nosegay increased, when suddenly from out the very heart of this plague, there stole a faint stream of perfume, which flowed through the tide of bad smells without being absorbed by it, as one river will flow into and then along with another, without at all blending with it for a time.</p>

            <p>"I have it, I have it," cried Stubb, with delight, striking something in the subterranean regions, "a purse! a purse!"</p>

            <p>Dropping his spade, he thrust both hands in, and drew out handfuls of something that looked like ripe Windsor soap, or rich mottled old cheese; very unctuous and savory withal. You might easily dent it with your thumb; it is of a hue between yellow and ash colour. And this, good friends, is ambergris, worth a gold guinea an ounce to any druggist. Some six handfuls were obtained; but more was unavoidably lost in the sea, and still more, perhaps, might have been secured were it not for impatient Ahab's loud command to Stubb to desist, and come on board, else the ship would bid them good bye.</p>

            <p>Now this ambergris is a very curious substance, and so important as an article of commerce, that in 1791 a certain Nantucket-born Captain Coffin was examined at the bar of the English House of Commons on that subject. For at that time, and indeed until a comparatively late day, the precise origin of ambergris remained, like amber itself, a problem to the learned. Though the word ambergris is but the French compound for grey amber, yet the two substances are quite distinct. For amber, though at times found on the sea-coast, is also dug up in some far inland soils, whereas ambergris is never found except upon the sea. Besides, amber is a hard, transparent, brittle, odorless substance, used for mouth-pieces to pipes, for beads and ornaments; but ambergris is soft, waxy, and so highly fragrant and spicy, that it is largely used in perfumery, in pastiles, precious candles, hair-powders, and pomatum. The Turks use it in cooking, and also carry it to Mecca, for the same purpose that frankincense is carried to St. Peter's in Rome. Some wine merchants drop a few grains into claret, to flavor it.</p>

            <p>Who would think, then, that such fine ladies and gentlemen should regale themselves with an essence found in the inglorious bowels of a sick whale! Yet so it is. By some, ambergris is supposed to be the cause, and by others the effect, of the dyspepsia in the whale. How to cure such a dyspepsia it were hard to say, unless by administering three or four boat loads of Brandreth's pills, and then running out of harm's way, as laborers do in blasting rocks.</p>
        </main>

        <footer>
            <p><small><em>Typography and color scheme based on <a href="http://typespiration.com/design/the-signal/">"The Signal"</a>.</em></small></p>
            <a id="back-to-top" href="#">Top</a>
        </footer>

JS

/*
             * - 변수 지정하기
             * - 문서의 높이를 계산하고 원하는 부분이 상단에서 얼마큼 떨어져 있는지 offset 값을 계산하기
             * - 스크롤과 클릭 이벤트 작성하기
             */

             var btt = document.getElementById('back-to-top'),
                docElem = document.documentElement, // html의 document 자체를 가져옴.
                offset, 
                scrollPos,
                docHeight;

            // 문서 최대 높이 계산하기
            // docHeight = docElem.scrollHeight;
            docHeight = Math.max(docElem.offsetHeight,docElem.scrollHeight);
            

            if(docHeight != 'undefined') { 
                offset = docHeight / 4; 
                 
            }
            // 스크롤 이벤트 추가('scroll')
            window.addEventListener('scroll', function(){
                scrollPos = docElem.scrollTop;
                console.log(scrollPos);

                btt.className = (scrollPos > offset) ? 'visible' : '';
            });

            // 클릭 이벤트 추가
            btt.addEventListener('click', function(event){
                event.preventDefault(); // 링크의 본연의 기능을 막는다. 
                // docElem.scrollTop = 0;
                scrollToTop();
            });
            function scrollToTop() {
                // 일정시간 마다 할일 
                // var scrollInterval = setInterval(할일, 시간);
                // 0.0015s = 15 
                // 할일 = function(){실제로 할일}
                /* 실제로 할일 : 윈도우 스크롤이 0이 아닐 때 실제로 할일 window.scrollBy(0,-55);
                                스크롤이 0이면 setInterval 멈춰라. clearInterval(이름);
                */ 

                var scrollInterval = setInterval(function(){
                    (scrollPos != 0) ? window.scrollBy(0, -300) : clearInterval(scrollInterval);
                }, 15);

            }

웹브라우저 마다(크롬, 파이어폭스) 높이를 계산하는 방식 다름
docHeight = docElem.scrollHeight;
docHeight = docElem.offsetHeight;

둘 중 가장 높은 값을 선택
그래서 Math.max 함수를 사용

0, '', 'undefined' 모두 같음

실시간 스크롤 양 console 나오게 하기

// 스크롤 이벤트 추가('scroll')
window.addEventListener('scroll', function(){
                scrollPos = docElem.scrollTop;
                console.log(scrollPos);
            });

back-to-top 버튼에 이벤트를 막고 바로 스크롤이 올라가야함.

<a id="back-to-top" href="#">Top</a>
btt.addEventListener('click', function(event){
                event.preventDefault(); // 링크의 본연의 기능을 막는다. 
			    docElem.scrollTop = 0;
            });

바로 스크롤을 올리는 것보다는 자연스럽게 스크롤이 올라가는 것이 좋다. 그러나 자바 스크립트에는 스크롤 지연 애니매이션 적용에 대한 메서드가 없어서 아래와 같이 작성해야함(jQuery는 스크롤 지연 애니매이션 메서드 기능 있음)

// 클릭 이벤트 추가
            btt.addEventListener('click', function(event){
                event.preventDefault(); // 링크의 본연의 기능을 막는다. 
                // docElem.scrollTop = 0;
                scrollToTop();
            });
            function scrollToTop() {
                // 일정시간 마다 할일 
                // var scrollInterval = setInterval(할일, 시간);
                // 0.0015s = 15 
                // 할일 = function(){실제로 할일}
                /* 실제로 할일 : 윈도우 스크롤이 0이 아닐 때 실제로 할일 window.scrollBy(0,-55);
                                스크롤이 0이면 setInterval 멈춰라. clearInterval(이름);
                */ 

                var scrollInterval = setInterval(function(){
                    (scrollPos != 0) ? window.scrollBy(0, -300) : clearInterval(scrollInterval);
                }, 15);

            }

전체 코드

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>JavaScript for Web Designers - Back to top button demo</title>

        <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Cormorant+Infant:700,700italic|Lato:400,400italic,700">
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <header id="top">
            <h1>Moby Dick</h1>
            <h2>by Herman Melville</h2>
        </header>

        <main>
            <p>Presently a breeze sprang up; Stubb feigned to cast off from the whale; hoisting his boats, the Frenchman soon increased his distance, while the Pequod slid in between him and Stubb's whale. Whereupon Stubb quickly pulled to the floating body, and hailing the Pequod to give notice of his intentions, at once proceeded to reap the fruit of his unrighteous cunning. Seizing his sharp boat-spade, he commenced an excavation in the body, a little behind the side fin. You would almost have thought he was digging a cellar there in the sea; and when at length his spade struck against the gaunt ribs, it was like turning up old Roman tiles and pottery buried in fat English loam. His boat's crew were all in high excitement, eagerly helping their chief, and looking as anxious as gold-hunters.</p>

            <p>And all the time numberless fowls were diving, and ducking, and screaming, and yelling, and fighting around them. Stubb was beginning to look disappointed, especially as the horrible nosegay increased, when suddenly from out the very heart of this plague, there stole a faint stream of perfume, which flowed through the tide of bad smells without being absorbed by it, as one river will flow into and then along with another, without at all blending with it for a time.</p>

            <p>"I have it, I have it," cried Stubb, with delight, striking something in the subterranean regions, "a purse! a purse!"</p>

            <p>Dropping his spade, he thrust both hands in, and drew out handfuls of something that looked like ripe Windsor soap, or rich mottled old cheese; very unctuous and savory withal. You might easily dent it with your thumb; it is of a hue between yellow and ash colour. And this, good friends, is ambergris, worth a gold guinea an ounce to any druggist. Some six handfuls were obtained; but more was unavoidably lost in the sea, and still more, perhaps, might have been secured were it not for impatient Ahab's loud command to Stubb to desist, and come on board, else the ship would bid them good bye.</p>

            <p>Now this ambergris is a very curious substance, and so important as an article of commerce, that in 1791 a certain Nantucket-born Captain Coffin was examined at the bar of the English House of Commons on that subject. For at that time, and indeed until a comparatively late day, the precise origin of ambergris remained, like amber itself, a problem to the learned. Though the word ambergris is but the French compound for grey amber, yet the two substances are quite distinct. For amber, though at times found on the sea-coast, is also dug up in some far inland soils, whereas ambergris is never found except upon the sea. Besides, amber is a hard, transparent, brittle, odorless substance, used for mouth-pieces to pipes, for beads and ornaments; but ambergris is soft, waxy, and so highly fragrant and spicy, that it is largely used in perfumery, in pastiles, precious candles, hair-powders, and pomatum. The Turks use it in cooking, and also carry it to Mecca, for the same purpose that frankincense is carried to St. Peter's in Rome. Some wine merchants drop a few grains into claret, to flavor it.</p>

            <p>Who would think, then, that such fine ladies and gentlemen should regale themselves with an essence found in the inglorious bowels of a sick whale! Yet so it is. By some, ambergris is supposed to be the cause, and by others the effect, of the dyspepsia in the whale. How to cure such a dyspepsia it were hard to say, unless by administering three or four boat loads of Brandreth's pills, and then running out of harm's way, as laborers do in blasting rocks.</p>
        </main>

        <footer>
            <p><small><em>Typography and color scheme based on <a href="http://typespiration.com/design/the-signal/">"The Signal"</a>.</em></small></p>
            <a id="back-to-top" href="#">Top</a>
        </footer>

        <script>
            /*
             * - 변수 지정하기
             * - 문서의 높이를 계산하고 원하는 부분이 상단에서 얼마큼 떨어져 있는지 offset 값을 계산하기
             * - 스크롤과 클릭 이벤트 작성하기
             */

             var btt = document.getElementById('back-to-top'),
                docElem = document.documentElement, // html의 document 자체를 가져옴.
                offset, 
                scrollPos,
                docHeight;

            // 문서 최대 높이 계산하기
            // docHeight = docElem.scrollHeight;
            docHeight = Math.max(docElem.offsetHeight,docElem.scrollHeight);
            

            if(docHeight != 'undefined') { 
                offset = docHeight / 4; 
                 
            }
            // 스크롤 이벤트 추가('scroll')
            window.addEventListener('scroll', function(){
                scrollPos = docElem.scrollTop;
                console.log(scrollPos);

                btt.className = (scrollPos > offset) ? 'visible' : '';
            });

            // 클릭 이벤트 추가
            btt.addEventListener('click', function(event){
                event.preventDefault(); // 링크의 본연의 기능을 막는다. 
                // docElem.scrollTop = 0;
                scrollToTop();
            });
            function scrollToTop() {
                // 일정시간 마다 할일 
                // var scrollInterval = setInterval(할일, 시간);
                // 0.0015s = 15 
                // 할일 = function(){실제로 할일}
                /* 실제로 할일 : 윈도우 스크롤이 0이 아닐 때 실제로 할일 window.scrollBy(0,-55);
                                스크롤이 0이면 setInterval 멈춰라. clearInterval(이름);
                */ 

                var scrollInterval = setInterval(function(){
                    (scrollPos != 0) ? window.scrollBy(0, -300) : clearInterval(scrollInterval);
                }, 15);

            }

        </script>
    </body>
</html>
* {
    box-sizing: border-box;
    -webkit-font-smoothing: antialised;
}

body {
    background-color: #313944;
    padding: 5em 20em;
}

h1 {
	color: #fff;
	font-family: 'Cormorant Infant';
	font-size: 72px;
	font-weight: 700;
	line-height: 72px;
	letter-spacing: -1px;
	margin-bottom: 48px;
	text-align: center;
}

    h1:after {
        color: #1fcfcb;
    	display: block;
    	content: '. . .';
    	font-size: 26px;
    	line-height: 24px;
    	height: 24px;
    	margin: 48px auto;
    }

h2 {
	color: #fff;
	font-family: 'Cormorant Infant';
	font-size: 54px;
	font-weight: 700;
	line-height: 72px;
	letter-spacing: -1px;
	margin-bottom: 48px;
	text-align: center;
}

p {
	color: #bbc8d8;
	font-family: 'Lato';
	font-size: 22px;
	font-weight: 500;
	line-height: 36px;
	margin-bottom: 36px;
	text-align: center;
}

a {
	color: #1fcfcb;
    font-family: 'Lato';
}

    a:hover {
    	color: #fff;
    }

#back-to-top {
    position: fixed;
    bottom: 3em;
    right: 3em;
    background-color: rgba(255, 255, 255, .9);
    color: #313943;
    border: none;
    border-radius: 5px;
    padding: 1em;
    text-transform: uppercase;
    cursor: pointer;
    font-weight: 700;
    box-shadow: 0 0 2em 0 rgba(0, 0, 0, .25);
    transition: all .3s ease-in-out;
    display: inline-block;
    opacity: 0; /* 투명도 0(안보임) */
    text-decoration: none;
    font-size: .75em;
}

    #back-to-top:hover {
        background-color: #fff;
        padding: 1em 3em;
    }

#back-to-top.visible {
    opacity: 1;
}

출처 : Rock's Easyweb 유튜브(https://www.youtube.com/watch?v=Mga3LXPnWdc)

profile
3년간 웹/앱, 자동제어 QA 🔜 개발자로 전향하여 현재 교육 회사에서 백엔드 개발자로 근무 중입니다.(LinkedIn : https://www.linkedin.com/in/dohyoung-kim-5ab09214b)

0개의 댓글