-
[JS ํฌํธํด๋ฆฌ์ค ๋ง๋ค๊ธฐ] ์คํฌ๋กค ์ ์๋จ๋ฐ ๊ณ ์ ๋ฐ ์์๋ฐ๊พธ๊ธฐMini Projects/make Portfolio 2022. 3. 18. 06:10
2022.03.17
๐คโ ํ์ด์ง๋ฅผ ์คํฌ๋กค ์, ์๋จ๋ฐ๊ฐ ๊ณ ์ ๋๋ฉด์ ์์์ด ๋ณํ๋๋ก ๋ง๋ค๊ณ ์ถ๋ค.
์ค๋๋ถํฐ๋ JS๋ฅผ ์ ํ ์กฐ๊ธ ๋ ํ์ด์ง๋ฅผ ๋์ ์ผ๋ก ๋ง๋๋ ค ํ๋ค.
ํ์ด์ง๋ฅผ ์คํฌ๋กค๋ง ํ ๋, ์๋จ์ ๋ค๋น๊ฒ์ด์ ๋ฐ๊ฐ ๊ณ ์ ๋๋๋ก ๋ง๋ค๊ณ , ์๋จ๋ฐ์ ์์์ ๋ณํ๋ฅผ ์ฃผ๋ ค ํ๋ค.
๐โํ์ฌ ์คํฌ๋กค๋ง ๋ Y๊ฐ์ ์ขํ๊ฐ ์๋จ๋ฐ์ Y๊ฐ ์ขํ๋ณด๋ค ํฌ๋ค๋ฉด ์๋จ๋ฐ๋ฅผ ๊ณ ์ ์ํจ๋ค.
๋ฐฉ๋ฒ์ ํฌ๊ฒ ๋๊ฐ์ง๋ก ๋๋ ์์๋ค.
ํ์ง๋ง ์ฒ์ ํ๋ก๊ทธ๋๋ฐ์ ํ๋ค๋ณด๋ ์๋จ๋ฐ๋ฅผ ๊ณ ์ ์ํค๋ ค๋ฉด ์ด๋ค ๋ช ๋ น์ ํด์ค์ผํ ์ง ๊ฐ์ด ์กํ์ง ์๋๋ค. ๊ทธ๋์ ์ผ๋จ์ ๋ฐฉ๋ฒ๋ก ์ ์ฐพ๊ธฐ๋ก ํ๋ค.
0) ๋ฐฉ๋ฒ๋ก ์ ์ฐพ์๋ณด์.
๋จผ์ , ๊ตฌ๊ธ์ ๋ค์ด๊ฐ ๊ตฌ๊ธ๋ง์ ํ๋ค.
๋๋ 'js fix navbar when scrolling'์ด๋ผ ๊ฒ์ํ๋ค. ์ผ๋ฐ์ ์ผ๋ก ์์ด๋ก ๊ฒ์ํ๋ ๊ฒ์ด ๋ ๋ง์ ์ ๋ณด๋ฅผ ์ป์ ์ ์๋ค.
๊ผญ ๋ฌธ์ฅ์ด ์๋๋๋ผ๋ ๋ณธ์ธ์ด ์ํ๋ ๋จ์ด๋ง ๋์ดํด๋ ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ค. ('js scroll topbar fix' ์ด๋ฐ ์์ผ๋ก)
๊ฐ์ฅ ์ฒ์ ๊ฒ์๋ How to create a sticky nav bar ๋ผ๋ ๋ฌธ์๋ฅผ ํตํด ์๋์ ๊ฐ์ ๋ด์ฉ์ ํ์ธํ๋ค.
์๋จ๋ฐ(navbar)์ Top์ขํ๊ฐ์ ๊ฐ์ ธ์ค๊ณ , ํ์ฌ ์คํฌ๋กคํ ์์น๊ฐ ์๋จ๋ฐ Y์ขํ๊ฐ์ด ๋ ํฌ๋ฉด 'sticky'๋ผ๋ ํด๋์ค๋ฅผ ๋ฃ์ด์ค๋ค.
์ด๋, 'sticky'๋ผ๋ ํด๋์ค๋ css์ ๋ฏธ๋ฆฌ ์ง์ ํด๋๋๋ค.
์ฐธ๊ณ ๋ก Y์ขํ๊ฐ์ ์ฐพ๋ ์ด์ ๋ ์คํฌ๋กค์ด '์์ง vertical'์ผ๋ก ์ด๋ค์ง๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฌผ๋ก ์ฒ์๋ถํฐ '์ ๊ทธ๋ ๊ตฌ๋'๋ผ๊ณ ์์ง๋ ๋ชปํ๊ธฐ์ ๋ค๋ฅธ์ฌ๋๋ค์ด ์ ์ฉํ ๋ฐฉ๋ฒ๋ก ๋ค๋ ๋ค ์ฐพ์๋ณธ ํ์, ๊ณตํต์ ์ผ๋ก ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์๊ฒ ๋๋ค. ํ์ง๋ง ๊ฐ๊ฐ ์ฌ์ฉํ๋ property๊ฐ ๋ฌ๋ผ ๊ฐ๊ฐ์ ๋ฐฉ๋ฒ์ ๋ํด ์ด๋ป๊ฒ ์ ์ฉํ๋ฉด ๋ ์ง ์์๋ณด๋ฉฐ ๊ฐ property์ ๋ํด์๋ ๋ญ๊ฐ ๋ค๋ฅธ์ง ์์๋ณด๋๋ก ํ๋ คํ๋ค.
1) ์ด๋ป๊ฒ ํ์ฌ ์คํฌ๋กค๋ง ๋ Y๊ฐ์ ์ขํ๋ฅผ ์์๋ผ๊น?
์ญ์ ๋จผ์ ๊ตฌ๊ธ๋ง์ ํ๋ค. 'how to know current y position mdn'์ด๋ผ ๊ฒ์ํ๋ window.scrollY๋ผ๋ ๋ฌธ์๋ฅผ ๋ณด์ฌ์ค๋ค.
scrollY: ์คํฌ๋กค๋ window์ ํ์ฌ Y์ขํ๊ฐ์ ์๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ค. scrollX: ์ํ๋ฐฉํฅ์ ์ขํ๋ฅผ ์๊ณ ์ถ๋ค๋ฉด scrollX๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
scrollY์ ๋๊ฐ์ ๊ธฐ๋ฅ์ ํ๋ property๊ฐ ์๋๋ฐ ๋ฐ๋ก window.pageYOffset์ด๋ค.
์ค๋๋ ๋ธ๋ผ์ฐ์ ์์๋ scrollY property๊ฐ ์๋๋์ง ์์ ์ ์๊ธฐ ๋๋ฌธ์ pageYOffset์ ์ฌ์ฉํ๋ฉด ๋๋ค๊ณ ํ๋ ๊ฒ์ ๋ณด๋ scrollY๊ฐ ๋ ์ต์ ๋ฌธ๋ฒ์ธ๊ฐ๋ณด๋ค. ๋ธ๋ผ์ฐ์ ๊ฐ์ ํธํ์ฑ์ ์ํด์๋ ์กฐ๊ฑด๋ฌธ์ ํตํด ๋๊ฐ์ง property๋ฅผ ๋ชจ๋ ์ฌ์ฉํ๋ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค.
ํ์ง๋ง ๋ธ๋ผ์ฐ์ ํธํ์ฑ์ ๋ณด๋ ๋ชจ๋ ๋ธ๋ผ์ฐ์ ์์ ์ ์ฉ๊ฐ๋ฅํ ๊ฒ์ผ๋ก ๋ณด์ ๊ทธ๋ฅ scrollY๋ฅผ ์ฌ์ฉํด๋ ๋ฌด๋ฐฉํ ๊ฒ ๊ฐ๋ค.
// ์คํฌ๋กค ์ navbar ๊ณ ์ ์ํค๊ธฐ document.addEventListener("scroll", () => { const scrollY = window.scrollY; console.log(scrollY) });
ํฌ๋กฌ ๊ฐ๋ฐ์๋๊ตฌ(mac ๋จ์ถํค: option + commnad + i)๋ก ํ์ธํด๋ณด๋ ์ ์๋ํ๋ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค.
2) ์๋จ๋ฐ์ Y๊ฐ(๋์ด๊ฐ)์ ์ด๋ป๊ฒ ์์๋ด์ง?
(1) Element.offsetTop
์ด์ ์๋จ๋ฐ์ Y๊ฐ ์ขํ๋ฅผ ์ฐพ์ผ๋ฉด ๋๋ค. how to know navbar y position mdn ๋ผ๊ณ ๊ฒ์ํ์ฌ Element.offseTop์ ํ์ธํ๋ค.
Element.offsetTop : ๊ฐ์ฅ ๊ฐ๊น์ด relative ์์ฑ์ ๊ฐ์ง ๋ถ๋ชจelement์ inner border์ top์์ ํ์ฌelement์ outer border๊น์ง ๊ฑฐ๋ฆฌ๋ฅผ ๋ฐํํ๋ค.
์ผ๋จ, ๋ถ๋ชจelement์์์ ๊ฑฐ๋ฆฌ๋ฅผ ์๊ณ ์ถ์๊ฒ ์๋๋ผ, ์๋์ฐ์์์ ๊ฑฐ๋ฆฌ๋ฅผ ์๊ณ ์ถ์๊ฑฐ๋ ํด๋น property๋ ๋ด๊ฐ ์ฐพ๋๊ฒ ์๋๊ฑฐ ๊ฐ๋ค.
๊ฒ๋ค๊ฐ ํฌ๋กฌ ๊ฐ๋ฐ์๋ชจ๋์์ ํ ์คํธํด๋ณด๋ ๊ฐ์ด ๊ณ ์ ๋์ง์๊ณ ๊ณ์ ์์ง์ธ๋ค. (Y๊ฐ์ ๋์ด๋ฅผ ๋ฐํํ๋ค๋ฉด ๊ฐ์ด ์ผ์ ์์ค์์ ๊ณ ์ ๋์ด์ผ ํ๋ค.)
(2) window.innerHeight
window ์์ชฝ์ ๋์ด๋ฅผ ๋ฐํํ๋ค. ํ์ง๋ง ๋ด๊ฐ ์๊ณ ์ถ์๊ฑด window ๋์ด๊ฐ ์๋๊ณ element์ ๋์ด์ด๋ ๋์ด๊ฐ๋ค.
์ฐธ๊ณ ๋ก clientHeight๋ผ๋ property๊ฐ ์๋ค. ์ด๋ ์คํฌ๋กค๋ฐ๋ border๊น์ง ์ ์ธํ ํ์ ์์ ๋ธ๋ผ์ฐ์ ํ์ด์ง์ ๋์ด๋ฅผ ๋ณด์ฌ์ค๋ค.
window.innerHeight: window - any borders element.clientHeight: window - (horizontal scrollbar + any borders)
(3) Element.getBoundingClientRect() / Element.clientHeight
clientHeight๊ฐ ์์ ๋ธ๋ผ์ฐ์ ์ฐฝ ์ฌ์ด์ฆ์ ํฌ๊ธฐ๋ฅผ ๋ฐํํ๋ ๊ฒ ๊ฐ์ผ๋ ํ๋ฒ ํ์ธํด๋ณธ๋ค.
Element.clientHeight: CSS height + CSS padding - horizontal scrollbar height
์ค, padding์ ํฌํจํ element์ ๋์ด๋ฅผ ์๋ ค์ค๋ค. ์ ์ง ์ด๊ฑฐ๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
์๋ ๋ด๋ ค๋ณด๋ element.getBoundingClientRect()๋ผ๋ property๊ฐ ์๋ค. clinetHeight๋ ๊ฐ์ ๋์ผํ ๊ธฐ๋ฅ์ ํ๋ ๊ฒ ๊ฐ๋ค.
element.clinetHeight: '์ ์ integer'๋ก ๊ฐ์ ๋ฐํ element.getBoundingClientRect(): '์์ float'๋ก ๊ฐ์ ๋ฐํ
๋๋ค ๋๊ฐ์ ์ญํ ์ ํ๋คํ๋ ๋๋ค ์ฌ์ฉํด๋ณด๋๋ก ํ๋ค.
const navbar = document.querySelector("#navbar"); //from HTML document.addEventListener("scroll", () => { const scrollY = window.scrollY; const clientHeight = navbar.clientHeight; const clientRect = navbar.getBoundingClientRect(); console.log(`scrollY: ${scrollY}`) console.log(`clientHeight: ${clientHeight}`); console.log(`clientRect: ${clientRect}`); });
ํฌ๋กฌ ๊ฐ๋ฐ์๋๊ตฌ๋ก ํ์ธํด๋ณด๋ ์ ์๋ํ๋ ๊ฒ ๊ฐ๋ค. ๊ทผ๋ฐ clientRect๋ 'Object DOMRect'๋ผ๊ณ ๋ฌ๋ค.
๋ญ๊ฐ ๋ฐฐ์ด(์ฌ๋ฌ๊ฐ์ง ๊ฐ์ด ์กฐํฉ๋์ด์)๋ก ์ด๋ค์ ธ์๋๋ณด๋ค. DOMRect๋ฅผ ๊ฒ์ํด๋ณด๋ ์ฌ๊ฐํ์ ์ฌ์ด์ฆ์ ํฌ์ง์ ์ ์ค๋ช ํ ๊ฒ์ด๋ผ ํ๋ค.
๊ทธ๋ ๋ค๋ฉด, ๋ญ๊ฐ element์ ๋ชจ๋ ์ ๋ณด๋ฅผ ๋ค ๋ด๊ณ ์๋ objectํํ๋ก ์ด๋ค์ ธ์๊ณ , ๊ทธ ์ค์์ ๋ด๊ฐ ์ํ๋ height๋ง ์!ํ๊ณ ๊ฐ์ ธ์ค๋ ๊ฒ์ด ์๋๊น!๋ผ๋ ์๊ฐ์ด ๋ ๋ค.
document.addEventListener("scroll", () => { ... const clientRect = navbar.getBoundingClientRect().height; //.height๋ฅผ ์ถ๊ฐํ๋ค. });
๊บ?! ๋ง๋ค?!!!ใ ใ ใ ใ ์ ๋๋ค.ใ ใ ใ ใ ์ ๋ญ๊ฐ ์ด๋ ๊ฒ ๊ฒ์ํด์ ์ฐพ์๋์ ๋์ ๋ฟ๋ฏํจ!!! ์ ๋๋ฌด ์ข๋ค.ใ ใ ใ ใ
3) ์ฝ๋ฉ์ ์ค์ํ๋ค.
์ํ๋ ์กฐ๊ฑด์ ๋ชจ๋ ์ฐพ์์ผ๋ ์ด์ ์ ์กฐํฉํด๋ณด๋๋กํ์.
(1) ์๋จ๋ฐ ๊ณ ์ ์ํค๊ธฐ
[css] /* navbar */ #navbar { display: flex; justify-content: space-between; position: fixed; /*navbar ์๋จ๊ณ ์ */ width: 100%; /*navbar๊ฐ ๊ฐ๋ก์์ญ 100% ์ฌ์ฉํ ์ ์๋๋ก ์ค์ */ color: var(--color-dark-gray); background-color: transparent; /*๊ธฐ๋ณธ์ผ๋ก ํฌ๋ช ์ผ๋ก ์ค์ ํ๋ค๊ฐ, ์คํฌ๋กค๋งํ๋ฉด ์์์ด ๋ณํ๋๋ก*/ transition: all var(--animation-duration) ease-in; /*์คํฌ๋กค๋งํ ๋ ์์ฐ์ค๋ฝ๊ฒ ์์ด ์ ํ์ง๋๋ก ์ ๋๋ฉ์ด์ ์ถ๊ฐ*/ } #navbar.fixed { background-color: var(--color-pink); }
์๋จ๋ฐ ๊ณ ์ ์ ์๊ฐ๋ณด๋ค ์ฌ์ ๋ค. position property๋ฅผ ์ด์ฉํด์ css์ ์๋จ๋ฐ(navbar)์ position์ "fixed"๋ก ๋ฐ๊ฟ์ฃผ๋ฉด ๋๋ค.
(2) ์๋จ๋ฐ ์์ ๋ฐ๊พธ๊ธฐ
์์์ ๋ฐ๊พธ๊ธฐ ์ํด์๋ css์ "fixed"๋ผ๋ ํด๋์ค๊ฐ ์ถ๊ฐ๋์ ๊ฒฝ์ฐ, ์ ์ฉ๋๋ ์กฐ๊ฑด์ ์ ๋ ฅํด์ค๋ค.
์คํฌ๋กค๋ง ํ๋ฉด ์์ด ์ ํ์ง๋๋ก ๊ธฐ์กด ์๋จ๋ฐ์ ์กฐ๊ฑด๋ ํฌ๋ช ํ๊ฒ ๋ฐ๊ฟ์คฌ๋ค.
[JS] // ์คํฌ๋กค ์ navbar ์์ ๋ฐ๊พธ๊ธฐ const navbar = document.querySelector("#navbar"); //from HTML const navbarHeight = navbar.getBoundingClientRect().height; document.addEventListener("scroll", () => { const scrollY = window.scrollY; //navbar์ ๋์ด๊ฐ ํ์ฌ๊น์ง ์คํฌ๋กค ๋ Y๊ฐ๋ณด๋ค ์๋ค๋ฉด navbar์ fixed๋ผ๋ ํด๋์ค๋ฅผ ๋ฃ์ด๋ผ. //1) ์ผํญ์ฐ์ฐ์ ์ฌ์ฉ navbarHeight < scrollY ? navbar.classList.add("fixed") : navbar.classList.remove("fixed"); //2) if๋ฌธ ์ฌ์ฉ if (window.scrollY > navbarHeight) { navbar.classList.add("fixed"); } else { navbar.classList.remove("fixed"); } });
JS๋ก ๋์ด๊ฐ์, ์คํฌ๋กค ์ ์๋จ๋ฐ์ ์ํ์ ๋ณํ๋ฅผ ์ฃผ๊ธฐ์ํด ์๋จ๋ฐ์ id(์ฌ๊ธฐ์์ "navbar")๋ฅผ ๋ถ๋ฌ์จ๋ค.
๊ทธ๋ฆฌ๊ณ ์๋จ๋ฐ์ ๋์ด๊ฐ ํ์ฌ๊น์ง ์คํฌ๋กค ๋ Y์ขํ๊ฐ๋ณด๋ค ์๋ค๋ฉด "navbar"๋ผ๋ id์ class "fixed"๋ฅผ ์ถ๊ฐํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด ์ ๊ฑฐํด๋ผ. ๋ผ๋ ๋ช ๋ น์ ์ ์ด์ค๋ค.
์กฐ๊ฑด๋ฌธ์ด์ด์ ์ผํญ์ฐ์ฐ์๋ก ์ ์ด๋ดค๋ค.
navbar์ classList์ถ๊ฐ๊ฐ ์ ๋ผ์๋์ง ํฌ๋กฌ ๊ฐ๋ฐ์๋ชจ๋์์ ํ์ธํด๋ณธ๋ค.
z-index
์ ๊ทธ๋ฐ๋ฐ ์๋๋ก ๋ด๋ฆฌ๋ ์๋จ๋ฐ ์์ชฝ์ผ๋ก ์ฌ๋ผ์ค๋ ์์๋ค์ด ์๋ค.
์ด๋ด๋์๋ css์์ ์๋จ๋ฐ์ z-index๊ฐ์ 1๋ก ์ฃผ๋ฉด ๋๋ค.
#navbar { display: flex; justify-content: space-between; position: fixed; /*navbar ์๋จ๊ณ ์ */ width: 100%; z-index: 1; /*๊ฐ์ฅ ์ต์์๋ก ์ฌ๋ผ์ค๋๋ก*/ color: var(--color-dark-gray); background-color: transparent; transition: all var(--animation-duration) ease-in; }
z-index๊ฐ ๋ญ์ผ? ๋ผ๊ณ ํ๊ธฐ์ ์ด๋ฆ์ด ๋ฑ ๋ด๋ ์ฌ์ฉ์ ์ชฝ์ผ๋ก ์ฌ๋ผ์ค๋ 3์ฐจ์ ์ถ์ ๋งํ๋ ๊ฒ ๊ฐ๋ค. ํด๋น ์ถ์ ๊ฐ์ฅ ์๋จ์ผ๋ก ์ฌ๋ฆฐ๋ค๋ ์๋ฏธ์ธ ๊ฒ ๊ฐ๋ค.
์์ฑ! ์๋จ๋ฐ ์ ๋๋ฉ์ด์ ์ด ์ ์ ์ฉ๋๋ค.
์ด๋ ๊ฒ
๋ญ๊ฐ, ์๋จ๋ฐ ํ๋ ๊ณ ์ ์ํค๊ณ ํฌ๋ช ํ๊ฒ ๋ง๋๋๋ฐ๋ ์ด๋ ๊ฒ ์๊ฐ์ด ๋ง์ด ๊ฑธ๋ฆด ์ค์ด์ผ... ์กฐ๊ธ ๋ฉ๋ถ์ด์์ง๋ง ์ด๋ ๊ฒ ํ๋์ฉ ์์๊ฐ๋๊ฑฐ๋ผ๊ณ ์๊ฐํ๋ค.
ํด๋น ํ๋ก์ ํธ๋ ์๋ github์ ์ ๋ก๋ํด๋์๋ค.
eunne's github: https://github.com/eunne/Project_Portfolio.git
'Mini Projects > make Portfolio' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ