-
[JS ํฌํธํด๋ฆฌ์ค ๋ง๋ค๊ธฐ] ์๋จ๋ฐ ๋ฒํผ ๋๋ฅด๋ฉด ํด๋น ํ์ด์ง๋ก ์คํฌ๋กคํ๊ธฐMini Projects/make Portfolio 2022. 3. 19. 09:20
2022.03.18-19
๐คโ ์๋จ ๋ฉ๋ด๋ฒํผ์ ๋๋ฅด๋ฉด ํด๋น ํ์ด์ง๋ก ์คํฌ๋กค ๋๋๋ก ๋ง๋ค๊ณ ์ถ๋ค.
์๋จ์ ๋์ด๋ ๋ฉ๋ด ๋ฒํผ์ ๋๋ฅด๋ฉด ํด๋น ํ์ด์ง๋ก ์คํฌ๋กค๋ง ๋๋๋ก ๋ง๋ค์ด๋ณด๋๋ก ํ๋ค.
๐โ๋ฉ๋ด ํ์ด์ง์ ์ขํ๊ฐ์ ๊ตฌํ์ฌ ์๋จ ๋ฉ๋ด๋ฒํผ์ ์ฐ๊ฒฐ์ํจ๋ค.
0) ๋ฐฉ๋ฒ๋ก ์ ์ฐพ์๋ณด์.
์์์ ์คํฌ๋กค๋ง์ ๋ํด ์์๋ด์ ๊ทธ๋ฐ์ง, ํด๋น property๋ฅผ ์์ฉํ๋ฉด ๋ ๊ฒ ๊ฐ๋จ ์๊ฐ์ด ๋ ๋ค.
element.getBoundingClientRect().y๋ฅผ ์ด์ฉํด ๋ฉ๋ดํ์ด์ง๋ค์ y์ขํ๋ฅผ ๊ตฌํ๊ณ , scrollto๋ฅผ ์ด์ฉํด์ ํด๋น y๊ฐ์ ์ฐ๊ฒฐ์์ผ ์ฃผ๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
1) ๊ฐ ๋ฉ๋ด ํ์ด์ง์ ์ขํ๊ฐ์ ๊ตฌํ์.
๋จผ์ , about์ y์ขํ๋ฅผ ๊ตฌํ๊ธฐ ์ํด element.getBoundingClientRect().y๋ฅผ ์ด์ฉํ์๋ค.
y๋ viewport์์๋ถํฐ content ์ข์ธก ์๋จ ๋ชจ์๋ฆฌ๊น์ง ๊ฑฐ๋ฆฌ๋ฅผ ๋งํ๋ค.
const about = document.querySelector("#about"); document.addEventListener("scroll", () => { console.log(about.getBoundingClientRect().y); });
์ฝ์๋ก ํ์ธํด๋ณด๋ #about content๊ฐ viewport์ ๋ฟ์ผ๋ ๋ฑ 0์ด ๋๋ค. padding์ ํฌํจํ๋ค.
๊ทธ๋ฐ๋ฐ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด๋ณด๋ ํ์ด์ง ์๋จ์ด ์๋จ๋ฐ์ ๊ฐ๋ฆฌ๊ฒ ๋จ์ผ๋ก viewport๋ง๊ณ , ์๋จ๋ฐ๋ฅผ ๊ธฐ์ค์ผ๋ก ํ์ด์ง๊ฐ ์คํฌ๋กค๋ง ๋์ด์ผ ํ๋ค.
๊ทธ๋์, ์๋จ๋ฐ์ ๋์ด๋งํผ์ ์ฐจ๊ฐ์์ผ์ฃผ๋ฉด, ๊ทธ๋งํผ ๋ ์ด๋ํ๊ฒ ๋ ๊ฑฐ๋ผ ์๊ฐํ์ฌ ์์์ ๋ง๋ค์๋ ์๋จ๋ฐ์ ๋์ด๋งํผ ์ฐจ๊ฐํด๋ดค๋ค.
const about = document.querySelector("#about"); document.addEventListener("scroll", () => { console.log(about.getBoundingClientRect().y - navbarHeight); });
์ค, ์๋จ๋ฐ ๋ฐ๋ก ์๋ y๊ฐ์ด 0์ด ๋๋๋ก ์ ๊ตฌํ๋๋ค. ๊ทธ๋ผ ์ด์ ์๋จ ๋ฉ๋ด๋ฒํผ์ ๋๋ฅด๋ฉด ์คํฌ๋กค๋๋ ๊ธฐ๋ฅ์ ์ ์ฉ์์ผ๋ณด์.
2) ์๋จ ๋ฉ๋ด๋ฒํผ์ ๊ฐ ํ์ด์ง๋ฅผ ์ฐ๊ฒฐ์ํค์
์๋จ ๋ฉ๋ด๋ฒํผ์ ๊ฐ ํ์ด์ง๋ฅผ ์ฐ๊ฒฐํ๊ธฐ ์ํด์๋ ์ด๋ป๊ฒ ํด์ผํ ๊น.
๋ฒํผ๋ง๋ค ํด๋์ค๊ฐ ์ง์ ๋์ด ์์ง ์์์ ๊ฐ ๋ฉ๋ด๋ณ๋ก ์ด๋ป๊ฒ ์ด๋ฒคํธ๋ฅผ ์ฐ๊ฒฐ์์ผ์ผํ ์ง ๋ชจ๋ฅด๊ฒ ๋ค.
๊ทธ๋ ๋ค๊ณ ๊ฐ ๋ฒํผ๋ง๋ค ํด๋์ค๋ฅผ ์ง์ ํ๋ ๋ฐฉ๋ฒ์ ์๋ ๊ฒ ๊ฐ์ง๋ง ์ผ๋จ ํ๋ฒ ์๋ํด๋ณธ๋ค.
์ผ๋จ ์๊ฐ๋๋ ๋ฐฉ๋ฒ์ผ๋ก๋ ๊ฐ ๋ฒํผ๋ง๋ค ํด๋น ํ์ด์ง์ ์ฐ๊ฒฐ๋๋ 'id'๋ฅผ ๋ฃ์ด์ ํด๋น 'id'๊ฐ ์ํ ์ขํ๋ก ์ด๋์ํค๋ ๊ฒ์ด๋ค.
(1) window.scrollTo
window.scrollTo๋ ๋ด๊ฐ ์ ๋ ฅํ ์ขํ๊ฐ๋งํผ ๋ฑ ํ๋ฒ๋ง ์ด๋ํ๋ค.
๊ทธ๋์ ๊ฐ ๋ฒํผ๋ง๋ค ํด๋น ํ์ด์ง์ ๋์ผํ 'id'๋ฅผ html์์ ๋ฃ์ด์ฃผ๊ณ , ํด๋น id์ y์ขํ๊ฐ์ ์ฐพ์, ScrollTo๋ก ์ฐ๊ฒฐ์์ผฐ๋ค.
gif
//1. html์์ ๊ฐ ๋ฒํผ๋ณ๋ก id๋ฃ์ ํ JS์์ ๋ถ๋ฌ์จ๋ค. const home = document.querySelector('#home'); const about = document.querySelector('#about'); const skillls = document.querySelector('#skills'); const work = document.querySelector('#work'); const tesimonials = document.querySelector('#testimonials'); const contact = document.querySelector('#contact'); //2. ํด๋น๋ฒํผ์ ๋๋ฅด๋ฉด 1์์ ๊ฐ์ ธ์จ 'id'๊ฐ ์ํ๋ ํ์ด์ง์ y์ขํ๋ฅผ ๊ฐ์ ธ์จ๋ค. //3. ๊ทธ๋ฆฌ๊ณ ํด๋น y๊ฐ์์ ์๋จ๋ฐ ๋์ด๋งํผ ์ฐจ๊ฐํ ์ขํ๊ฐ๊น์ง ์คํฌ๋กคํ์ฌ ์ด๋ํ๋ค. home.addEventListener("click", () => { const rect = home.getBoundingClientRect(); scrollTo(0,rect.y - navbarHeight); }); about.addEventListener("click", () => { const rect = about.getBoundingClientRect(); console.log(scrollTo(0,rect.y - navbarHeight)); }); ...
์ค, ๋ฒํผ์ ๋๋ฅด๋, ์์์ ์ง์ ํ ํ์ด์ง๊น์ง ์ ์ด๋ํ๋ค.
๊ทธ๋ฐ๋ฐ ๋ฌธ์ ๊ฐ ์๊ฒผ๋ค. ์ ๋ฉ๋๋ก ์ด๋ํ๋ค. ์ผ๊ด๋์ง ์์์ด๋...
(2) event.target
event
ํด๋ตํธ์์ ์ฝ๊ฐ ํํธ๋ฅผ ์ป์๋ค. ๋ฐ๋ก event๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค.
๊ฐ ๋ฉ๋ด๋ฒํผ์ ๋๋ฅด๋ฉด ํด๋น ๋ฉ๋ด๋ฒํผ์ด ์ด๋ฒคํธ๋ก ๋ค์ด์ ์นด์ดํธ๊ฐ ์ฌ๋ผ๊ฐ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
const navbarMenu = document.querySelector('.navbar__menu'); navbarMenu.addEventListener('click', (event) => { console.log(event); });
event.target
๊ทธ๋ฌ๋ฉด ๋ด๊ฐ ๋๋ฅธ ๋ฒํผ์ ์ด๋ป๊ฒ 'ํน์ '์ํฌ ์ ์์๊น?
๋ฐ๋ก event.target property๋ฅผ ์ฌ์ฉํ๋ฉด ๋ด๊ฐ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํจ ๊ทธ ๊ฐ์ฒด๊ฐ ๋ฐํ๋๋ค.
const navbarMenu = document.querySelector('.navbar__menu'); navbarMenu.addEventListener('click', (event) => { console.log(event.target); });
(3) data- ์์ฑ
์ต์ข ์ ์ผ๋ก๋ ๋ด๊ฐ ๋๋ฅธ ๋ฒํผ์ ํด๋นํ๋ ์์น๋ก ์ด๋ํ๊ณ ์ถ์ ๊ฒ์ด๋ฏ๋ก, ๋ฒํผ ๋ด๋ถ์ ํด๋น ํ์ด์ง์ ์ฐ๊ฒฐ๋๋ '์ ๋ณด'๋ฅผ ์ถ๊ฐํด์ฃผ๋ฉด ๋๋ค.
์, ๊ฒฐ๊ตญ์๋ ๊ฐ ๋ฒํผ๋ง๋ค 'id'๋ฅผ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ์ ๋ง๋ ๊ฒ ๊ฐ๋ค. ๋ค๋ง ๋๊ตฌ๊ฐ ๋ค๋ฅผ ๋ฟ.
data- ์์ฑ?
HTML์ ๋ฐ์ดํฐ์์ฑ (data-*)์ด๋ผ๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ๊ฐ ๋ฒํผ๋ง๋ค 'id'๋ฅผ ์ถ๊ฐํ๋ค.
๋ฐ์ดํฐ์์ฑ์ ํน์ ์์์ ์ฐ๊ฒฐ๋์ด ์์ง๋ง ํ์ ๋ ์๋ฏธ๋ ๊ฐ์ง ์๋ ์์ฑ์ด๋ค. DOM๊ณผ ๊ฐ์ด ๋ค๋ฅธ ์์ฑ์ ์กฐ์ ์์ด๋ ์ด์ฉ ๊ฐ๋ฅํ๋ค.
๋ญ๊ฐ ์๋ฏธ๋ ์์ง๋ง ๋ค๋ฅธ ๋ฌธ๋ฒ๊ณผ '์ฐ๊ฒฐ'์ํฌ ๋ ์ฌ์ฉํ๊ธฐ ์ข์ ์์ฑ์ธ ๊ฒ ๊ฐ๋ค.
๊ฒ๋ค๊ฐ ๊ณ์ ๋ณํ๋ ์ ๋ณด๋ ์ ์ฅํ ์ ์๋ค. ๊ทธ๋์ display๊ท์น์ ์ฌ์ฉํ์ง ์๊ณ ๋ ํด๋น ํจ๊ณผ๋ฅผ ๋ง๋ค ์ ์๋ค. (๊ณ ํ๋๋ฐ ๋ฌด์จ์๋ฆฐ์ง๋ ์์ง ์ ๋ชจ๋ฅด๊ฒ ๋ค.)
JS์์๋ getAttribute() ๋๋ dataset ์ผ๋ก ํด๋น ์ ๋ณด๋ฅผ ์ฝ์ ์ ์๋ค.
CSS์์๋ ์ญ์ ํด๋น ์ ๋ณด๋ฅผ ์ฝ์ด์ฌ ์ ์๋ค.
data-link๋ผ๋ ์์ฑ์ ์ฌ์ฉํด๋ณด์
<ul class="navbar__menu"> <li class="navbar__menu__item active" data-link="#home">Home</li> <li class="navbar__menu__item" data-link="#about">About me</li> <li class="navbar__menu__item" data-link="#skills">Skill</li> <li class="navbar__menu__item" data-link="#work">My Work</li> <li class="navbar__menu__item" data-link="#testimonials">Testimonial</li> <li class="navbar__menu__item" data-link="#contacts">Contact</li> </ul>
HTML์ ๊ฐ ๋ฒํผ๋ง๋ค data- ์์ฑ์ ์ฌ์ฉํด 'link'๋ผ๋ ๊ณณ์ ํด๋น 'id'๋ค์ ๋ด์๋๋ค.
const navbarMenu = document.querySelector('.navbar__menu'); navbarMenu.addEventListener('click', (event) => { const target = event.target; const link = target.dataset.link; console.log(event.target.dataset.link); });
JS์์ data์์ฑ์ ๋ถ๋ฌ์ฌ ๋๋ ์์์ ๋งํ๊ฒ ์ฒ๋ผ dataset์ ์ด์ฉํ๋ฉด ๋๋ค.
dataset์์ link๋ฅผ ๋ถ๋ฌ์ค๊ฒ ๋๋ฉด ์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ๊ฐ ๋ฒํผ์ id๊ฐ์ ๋ฐํํด์ค๋ค.
๊ทธ๋ฐ๋ฐ ์๋จ๋ฐ ๋ฉ๋ด์์ data์์ฑ์ ์ ์ํด์ฃผ์ง ์์ ๋ถ๋ถ์ ๋๋ฅด๊ฒ ๋๋ฉด undefined๋ก ๋จ๋ ๋ถ๋ถ์ด ์๋ค. ๊ทธ๋์ ํด๋น๋ถ๋ถ์ ๋๋ ์ ๋ ์๋ฌด๋ฐ ๋ฐ์์ ํ์ง ์๋๋ก ์ฒ๋ฆฌํด์ค์ผ ํ๋ค.
const navbarMenu = document.querySelector('.navbar__menu'); navbarMenu.addEventListener('click', (event) => { const target = event.target; const link = target.dataset.link; console.log(event.target.dataset.link); //link๋ฅผ ๋๋ ์ ๋ null (์๋ฌด๊ฒ๋ ๋ค์ด์์ง ์๋ค๋ฉด) ๊ทธ๋ฅ return์ ์ํจ๋ค. //์์ธ์กฐ๊ฑด์ ์์์ ์ฒ๋ฆฌํด์ฃผ๊ณ , else๋ถ๋ถ์ ์ํ๋ ๋์์ ๋ฃ๋๋ค. if (link == null) { return; } else { };
์์ฝํ์๋ฉด event.target๊ณผ dataset์ ์กฐํฉ์ ํตํด ๊ฐ ๋ฒํผ์ 'id'๊ฐ์ ๋ถ๋ฌ์ฌ ์ ์๋ค.
(4) element.scrollIntoView()
๋ฒํผ์ ์ ํํ์ ๋, ์ํ๋ ์์น๋ก ์ด๋ํ๊ธฐ ์ํด์ ๋๋ 'id์ ์์น๊ฐ + scrollTo'๋ฅผ ์ด์ฉํ๋๋ฐ, ์ด๊ฒ๋ณด๋ค ๋ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ด ์์๋ค.
๋ฐ๋ก scrollIntoView๋ผ๋ ์์ฑ์ธ๋ฐ ํธ์ถ๋ ์์์ ์์ ์ปจํ ์ด๋๊น์ง ์คํฌ๋กค๋ง ํด์ค๋ค. ์ฆ, id์ ์์น๊ฐ์ด ์์ด๋ id๋ง ์๋ค๋ฉด ํด๋น ์์น๊น์ง ์๋์ผ๋ก ์คํฌ๋กคํด์ค๋ค๋ ์๋ฏธ๋ค.
์ปจํ ์ด๋์ ์๋จ ๋๋ ํ๋จ ๋ฑ ์ด๋์์น๋ก ์ด๋์ํฌ์ง option์ ํตํด ์กฐ์ ํ ์ ์๋ค.
const navbarMenu = document.querySelector('.navbar__menu'); navbarMenu.addEventListener('click', (event) => { const target = event.target; const link = target.dataset.link; console.log(event.target.dataset.link); if (link == null) { return; } else { const scroll = document.querySelector(link); scroll.scrollIntoView({behavior:"smooth"}); //option์ผ๋ก ์ ๋๋ฉ์ด์ ์ smoothํ๊ฒ ๋ง๋ ๋ค } });
์ง ! ๋ถ๋๋ฝ๊ฒ ์ ์ด๋ํ๋ค.
๊ทธ๋ฐ๋ฐ ์๋จ๋ฐ ๋ฐ๋ก ๋ฐ์ผ๋ก ์ค๋๋ก ๋ง๋ค๊ณ ์ถ์๋ฐ ๊ทธ๊ฑด scrollintoview๋ก๋ ์๋๋๊ฑธ๊น.
๋ค๋ฅธ ๊ธฐ๋ฅ๋ค์ ์ข ๋ ์ ๋ฆฌํด๋ณด๊ณ ํ ์คํธ์ข ํด๋ด์ผ๊ฒ ๋ค.
3) ๊ทธ๋์ hash table ํํ์ ํจ์๋ฅผ ์ฌ์ฉํ๋๊ฒ ์๋๊น. (์๊ฐ๋ณต์ก๋๋ฅผ (0)1๋ก?!)
getBoundingClientRect๋ ๊ทธ๋ ๊ณ scrollIntoView๋ ๊ทธ๋ ๊ณ ํ๋์ ๊ฐ์ ์ ๊ทผํ๋ ์์ฑ๋ณด๋ค๋
objectํํ๋ก ๋ฌถ์ด์ ์ฌ๋ฌ๊ฐ์ ์ ๊ทผํ๋ ์์ฑ์ ๋ ๋ง์ด ์ด์ฉํ๋ ๊ฒ ๊ฐ๋ค. (objectํํ์ ์ ๊ทผํด ๊ทธ ์์์ ์ต์ ์ ํตํด ์ํ๋ ๊ฐ์ ์ ํ)
์๋ฌด๋๋ ๋ ๋น ๋ฅธ ์ฝ๋๋ฅผ ์ํด์ ์์ ๊ฐ์ hash table๊ตฌ์กฐ๋ก ๋ณด์ด๋ ํจ์๋ค์ ์ฌ์ฉํ๋ ๊ฒ ๊ฐ๋ค. ๋ฐฐ์ด์ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง Hash table(JS์์๋ object)๋ก ์ ๊ทผํ๊ฒ๋๋ฉด ์๊ฐ๋ณต์ก๋๊ฐ (0)1์ด๊ธฐ ๋๋ฌธ์ ์๊ณ ๋ฆฌ์ฆ ํจ์จ์ฑ์ด ๋งค์ฐ๋งค์ฐ ์ฆ๊ฐํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ขํ๊ฐ์ ์ฐพ๋ ํจ์๋ค, ๊ทธ๋ฆฌ๊ณ ์คํฌ๋กค๋งํ๋ ํจ์๋ค์ด ๊ฝค ์๋๋ฐ ์ด ์ค์์ ์์ ์ฌ์ฉํ ํจ์๋ค์ด ๋น๊ต์ '์ต๊ทผ์'๋์จ ํจ์์ด์ง ์์๊น ์ถ๋ค. ์ด๋ฒ์ ๊ณต๋ถํ๋ฉด์ ๋ค์ํ ํจ์๋ค์ ๋ดค๋๋ฐ ๋๋ฌด ํท๊ฐ๋ ค์ ๊ฐ ํจ์๋ค์ ๋ํด์๋ ์ ๋ฆฌ๋ฅผ ํด์ผ๊ฒ ๋ค.
[ํท๊ฐ๋ฆฌ๋ ํจ์๋ค]
- queryselector / getelementbyid
- scrollby / scrollto / scrollinto / scrollintoview
- getBoundingClientRect /
eunne's github: https://github.com/eunne/Project_Portfolio.git
'Mini Projects > make Portfolio' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ