2์ฃผ์ฐจ ๋ง์ง๋ง ๋ ์ ๊ณผ์ ๋ก HTML, CSS, JavaScript๋ฅผ ์ด์ฉํด์ ์๊ธฐ์๊ฐ ํ์ด์ง๋ฅผ ์ ์ํ๋ ๊ณผ์ ๊ฐ ์ฃผ์ด์ก๋ค.
๋ฉ์ฌ์์ ํ๋ํ์ ๋๋ HTML/CSS๋ฅผ ๋ฐฐ์ฐ๊ณ ๊ฐ๋ณ๊ฒ ์๊ธฐ์๊ฐ ํ์ด์ง ์ ์ ๊ณผ์ ๋ฅผ ํ์๋๋ฐ, ํ์คํ ๊ทธ ๋๋ณด๋ค ์ด๋ฐ์ ๋ฐ ์์๋ค์ ์ ๋ฒ ๋ค๋ฃฐ ์ ์๊ฒ ๋ ๊ฒ์ ๋๊ผ๋ค.
๊ทธ ๋ ๊ฐ์ด ํ๋ํ๋ ๋์๋ฆฌ์ ์ค, ์น ํ๋ฉด์ ํ์ด์ง๋ฅผ ๊ฝ ์ฑ์์ ์ฌ๋ฌ ํ์ด์ง๋ค์ ์คํฌ๋กค ํ๋ ๋ฐฉ์์ผ๋ก ์ ์ํ์ ๋ถ์ด ๊ณ์ จ๋๋ฐ, ๋น์ ์น ๊ฐ๋ฐ ํ๋ณ์๋ฆฌ์๋ ๋๋ ๊ทธ๋ฐ ์ ์ธ๊ณ(?) ๋์์ธ์ ์ฒ์ ์ ํด๋ดค์๊ณ ๋ค์์ ํ ๋ฒ ์ ๋ ๊ฒ ๋ง๋ค์ด ๋ณด๊ณ ์ถ๋ค๋ ์๊ฐ์ ํ์๋ค.
๊ทธ ์ธ์๋ ๋ฅ๋ ฅ์ด ๋ถ์กฑํด์ ํด๋ณด๊ณ ๋ ์ถ์ง๋ง ๊ตฌํ์ ๋ชปํ๋ ๊ฒ๋ค์ด ๋ง์์ด์, ์ด๋ฒ ๊ณผ์ ์ ํ์ด์ง ๋์์ธ์ ๋น์๋ฅผ ํ์ํ๋ฉด์ ํ๋ค.
๊ณผ์ ์ ์ฃผ์ ๊ฐ ํ์ ๋ด์ฉ๋ค์ ์ฝ์ ํ๋, ์ง๊ธ๊น์ง ๋ฐฐ์ด HTML/CSS, JavaScript๋ฅผ ํ์ฉํด์ ์์ ์ ์๊ฐํ๋ ํ์ด์ง๋ฅผ ๋ง๋๋ ๊ฒ์ด์๊ธฐ ๋๋ฌธ์ ๊ฐ๋จํ๊ฒ JavaScript๋ฅผ ์์ฉํด๋ณด๋ ํ์ด์ง๋ ํ๋ ๋ง๋ค์ด๋ณด๊ธฐ๋ก ํ๋ค.
navbar๋ ์์น๋ฅผ ๊ณ ์ ํ๊ธฐ ์ํด์ position: relative / absolute๋ฅผ ์ฌ์ฉํ๋ค. ๋ ul๊ณผ li๋ฅผ ์ด์ฉํด์ ํญ์ ๋ง๋ค์๊ณ , flex ์์ฑ์ ํตํด ๊ฐ๋ก์ ๋ ฌ์ ํด์คฌ๋ค. ๊ฐ li๋ ํด๋น ํ์ด์ง๋ก ์ด๋ํ๋ ๊ธฐ๋ฅ์ ๊ตฌํํ๊ธฐ ์ํด์ ํ ์คํธ๋ฅผ aํ๊ทธ๋ก ๊ฐ์๋ค.
<ul>
<li><a href="" class="menu1" onclick="location.replace(location.href);"><span>HOME</span></a></li>
<li><a href="#section2" class="menu2"><span>ABOUT</span></a></li>
<li><a href="#section3" class="menu3"><span>INTEREST</span></a></li>
<li><a href="#section4" class="menu4"><span>GOAL</span></a></li>
<li><a href="#section5" class="menu5"><span>FAVORITE</span></a></li>
<li><a href="#section6" class="menu6"><span>CHANGE</span></a></li>
<li><a href="#section7" class="menu7"><span>END</span></a></li>
</ul>
๋ด๊ฐ ์์ฑํ ๋ฐฉ์์ html์ aํ๊ทธ๋ฅผ ์ด์ฉํด์ ๊ฐ ํ์ด์ง๋ก ์ด๋ํ๋ ๋ฐฉ์์ธ๋ฐ, ์ง๊ธ ๋ณด๋ JavaScript window ๊ฐ์ฒด์ scrollTo ๋ฉ์๋ ๊ฐ์ ๊ฒ์ผ๋ก ๊ตฌํํด ๋ณด์๋ค๋ฉด ๋ ์ข์ง ์์์๊น ํ๋ ์์ฌ์์ด ๋ ๋ค.
๋ฉ์ธ ํ์ด์ง์ ํ์ดํ ํจ๊ณผ๋ JavaScript์ innerHTML์ ์ด์ฉํด์ ๊ตฌํํ๋ค. ์ด ๋ธ๋ก๊ทธ์ ๊ธ์ ์ฐธ๊ณ ํ๊ณ , ์ ๋ง ๋ง์ ๋์์ด ๋์๋ค!
const content = "Welcome!";
const text = document.querySelector(".welcome");
let i = 0;
function typing() {
if (i < content.length) {
let txt = content.charAt(i);
text.innerHTML += txt;
i++;
}
}
setInterval(typing, 300)
๊ทธ๋ฆฌ๊ณ ๊ฐ ํ์ด์ง๋ฅผ ์คํฌ๋กคํ๋ฉฐ ์ด๋ํ ๋, Scroll snap์ ์ด์ฉํด์ ์ผ์ ๋ถ๋ถ ์ด์์ด ์คํฌ๋กค๋๋ฉด ๋ค์ ํ์ด์ง๊ฐ ์๋์ผ๋ก ํ๋ฉด ์๋จ์ผ๋ก ์ค๋ ๋๋ ํจ๊ณผ๋ฅผ ๊ตฌํํ๋ค.
.container {
width: 100%;
height: 100vh;
overflow: auto;
scroll-behavior: smooth;
scroll-snap-type: y mandatory;
}
.section {
position: relative;
height: 100vh;
scroll-snap-align: start;
background-color: #ffecb3;
}
๊ฐ ํ์ด์ง ์ค๋ฅธ์ชฝ ํ๋จ์๋ scroll back to top ๋ฒํผ์ ์์ฑํด์, ์ด๋ ํ์ด์ง์์๋ ์น ํ์ด์ง์ ์ต์๋จ์ผ๋ก ์ด๋ํ ์ ์๊ฒ ํ๋ค. ์ด ๋์ ์คํฌ๋กค ๊ธฐ๋ฅ ๋ํ aํ๊ทธ๋ฅผ ์ด์ฉํ๋ค.
<a href="#top_line"><span><img class="top_img" src="top-icon.jpg"></span></a>
๋ด๊ฐ ์ข์ํ๋ ๊ฒ๋ค์ ๋ํ๋ด๋ ํ์ด์ง๋, ์ข์ํ๋ ๊ฒ๋ค์ ์์ํ๋ ๋ํ ์ด๋ฏธ์ง๋ค์ ์ฝ์ ํ๊ณ ํด๋น ์ด๋ฏธ์ง๋ค์ ๋ง์ฐ์ค๋ฅผ ์ฌ๋ ธ์ ๋ ํ ์คํธ๊ฐ ๋ํ๋๋๋ก ๊ตฌํํ๋ค. CSS์ hover๋ก ๊ฐ๋จํ ๊ตฌํ๋ ์ค ์์๋๋ฐ, ์ด๋ฏธ์ง์ ํ ์คํธ๊ฐ ๊ฐ๊ฐ ๋ค๋ฅธ ํ๊ทธ๋ก ์์ฑ๋์ด ์์ด์, ์ด๋ฏธ์ง๊ฐ hover ๋์์ ๋ ํ ์คํธ์ display๋ฅผ none์์ block์ผ๋ก ๋ณ๊ฒฝํ๋ ๊ฒ์ด ์๊ฐ๋ณด๋ค ๊น๋ค๋ก์ ๋ค. ๊ทธ๋์ JavaScript๋ฅผ ์ด์ฉํด์ ํจ๊ณผ๊ฐ ์์ฑ๋ class๋ฅผ ์ถ๊ฐํ๋ ๋ฐฉ์์ผ๋ก ๊ตฌํํ๋ค.
const fav_image = document.querySelectorAll('.fav_image');
fav_image.forEach((fav) => fav.addEventListener('mouseover', hoverEvent));
fav_image.forEach((fav) => fav.addEventListener('mouseout', hoveroutEvent));
function hoverEvent() {
this.querySelector('.fav_image > img').classList.add('hovered_img');
this.querySelector('.img_title').classList.add('hovered_front');
}
function hoveroutEvent() {
this.querySelector('.fav_image > img').classList.remove('hovered_img');
this.querySelector('.img_title').classList.remove('hovered_front');
๋ง์ง๋ง์ผ๋ก JavaScript ์์ฉ ํ์ด์ง๋ ๋ค์์ฃผ์ ํ์ตํ๋ ์ด๋ฒคํธ๋ฅผ ์์ตํ๋ ์ฐจ์์์, e.target์ ์ด์ฉํด์ ๋ง๋ค์๋ค. ๋ฐฉ๋ฌธ์์ ์ด๋ฆ์ ๋ฐ์์์ ์ถ๋ ฅํ๊ณ , 6์๋ฆฌ์ ์์ ์ฝ๋๋ฅผ ์ ๋ ฅ๋ฐ์์ ์๊ธฐ์๊ฐ ํ์ด์ง์ ๋ฐฐ๊ฒฝ ์์์ ๋ณ๊ฒฝํ๋ ๊ธฐ๋ฅ์ด ์๋ค.
const color_input = document.querySelector('.color_input');
const section = document.querySelectorAll('.section');
const section6_mid = document.querySelector('.section6_mid');
color_input.addEventListener('change', (e) => {
section.forEach((s) => s.style.setProperty("background", `#${e.target.value}`));
section6_mid.innerHTML = `<span>์
๋ ฅํ์ ์์ ์ฝ๋๋ #${e.target.value} ์
๋๋ค.</span>`;
});
const reset_btn = document.querySelector('.reset_btn');
reset_btn.addEventListener('click', () => {
section.forEach((s) => s.style.setProperty("background", `#ffecb3`));
section6_img.src = "2.png";
section6_bubble.innerHTML = `<input type="text" class="name_input" placeholder="๋ฐฉ๋ฌธ์๋, ๋น์ ์ ์ด๋ฆ์ ๋ฌด์์ธ๊ฐ์?">`;
section6_mid.innerHTML = `<input type="text" class="color_input" placeholder="์ํ๋ ์์์ฝ๋ ์ฌ์ฏ์๋ฆฌ๋ฅผ ์
๋ ฅํด๋ณด์ธ์! ์) e9e9e9">`;
});
const name_input = document.querySelector('.name_input');
const section6_img = document.querySelector('.section6_img');
const section6_bubble = document.querySelector('.section6_bubble');
name_input.addEventListener('change', (e) => {
section6_img.src = "3.png";
section6_bubble.innerHTML = `
<span>์๋
ํ์ธ์, ${e.target.value} ๋!
<br>
์๋์ ์
๋ ฅ์นธ์ ํตํด ์ ํํ์ด์ง ์์ ๋ณ๊ฒฝํด๋ณด์ธ์ ๐จ
</span>`;
});
๐ ์ต์ข ์ ์ผ๋ก ์์ฑ๋ ๊ฒฐ๊ณผ๋ฌผ์ ์ฌ๊ธฐ์์ ๋ณผ ์ ์๋ค.
๊ณผ์ ๋ฅผ ์ํํ๋ฉด์ ๊ณผ๊ฑฐ์ ๋นํด ๋ง์ด ๋ฐ์ ๋ ๊ฒ์ ๋๋ ์ ์์์ง๋ง, ํํธ์ผ๋ก๋ ์์ง๋ ๋ถ์กฑํจ์ด ๋ง์ด ๋๊ปด์ง๊ธฐ๋ ํ๋ค.
CSS์ position์ด๋ transform์ ์ฌ์ฉํ๋ ๋ฐ์ ์์ด์ ์์ง ๋ฏธ์ํ ์ ์ด ์์๊ณ , JavaScript๋ฅผ ์๊ฐ๋งํผ ์์ ์์ฌ๋ก ๋ค๋ฃจ๋ ๊ฒ์ ์ฌ์ ํ ์ฝ์ง ์์๋ค. ์์ง๋ ๊ฐ ๊ธธ์ด ๋ฉ๋ค๐
์๊ธฐ์๊ฐ ํ์ด์ง์ ์ ํ ๊ฒ ์ฒ๋ผ ์ด์ฌํ ๋ฐฐ์ฐ๋ฉฐ, ์ฑ์ฅ์ ๊ฑฐ๋ญํ๋ ๊ฐ๋ฐ์๊ฐ ๋๊ธฐ ์ํด ๊พธ์คํ ๋ ธ๋ ฅํด์ผ๊ฒ ๋ค.