(포트폴리오에 들어간 내비게이션)
깔끔하면서도 역동적인(?) 내비게이션 효과를 만들고 싶어서 유튭 강의와 코드펜에 올라온 코드들을 참고해서 만들었습니다.
TIL용으로 코드펜에 바닐라JS로 심플하게 정리했습니다.
코드펜에 작성한 내용을 바탕으로 설명드리겠습니다!
<nav id="nav" class="nav">
<ul class="nav__menu">
<li><a href="#one"class="nav__menu--foused">ONE</a></li>
<li><a href="#two">TWO</a></li>
<li><a href="#three">THREE</a></li>
<li><a href="#four">FOUR</a></li>
<div class="marker"></div>
</ul>
</nav>
<section id="one">one</section>
<section id="two">two</section>
<section id="three">three</section>
<section id="four">four</section>
nav를 만들어서 안에 메뉴를 집어넣어주고 href를 해당 섹션의 id 값으로 설정해줍니다.
marker도 만들어 주시는 거 잊지말기!
너무 길어서 marker 부분만 정리...
.marker {
content: "";
position: absolute;
bottom: 1.2rem;
left: 50%;
width: 0%;
height: 3px;
background-color: purple;
transition: 0.2s;
}
width와 left는 javaScript에서 설정하는 부분입니다.
스크롤을 하면 보이는 설정이기 때문에 width를 0으로 했습니다.
left는 왜 50%로 했냐
새로고침을 했을 때 nav의 왼쪽 끝에서 marker가 달려오는 것보다 가운데에서 달려오는 게 좀 더 멋있기때문입니다.
취향대로 하시면 됩니다.
const marker=document.querySelector(".marker");
function setMarker(e) {
marker.style.left = e.offsetLeft+"px";
marker.style.width = e.offsetWidth+"px";
}
좌표 구하는 프로퍼티는 항상 헷갈려서 그림으로 그려왔습니다.
const sections = document.querySelectorAll("section");
const menus = document.querySelectorAll(".nav__menu > li > a")
window.addEventListener("scroll",()=>{
//현재 영역의 id 값
let current=""
sections.forEach(section=>{
//각 section의 top 위치(절대적 위치)
// The top of each section (absolute)
const sectionTop = window.scrollY + section.getBoundingClientRect().top;
//누적된 스크롤이 section의 top위치에 도달했거나 section의 안에 위치할 경우
if(window.scrollY >= sectionTop) {
current = section.getAttribute("id");
}
})
element.getBoundingClientRect()에 대한 설명은 이쪽으로
menus.forEach(menu=>{
menu.classList.remove("nav__menu--foused");
const href = menu.getAttribute("href").substring(1);
if(href===current) {
//현재 있는 영역의 id와 메뉴의 링크주소가 일치할때
//When the Id of the current section matches the href of the menu
menu.classList.add("nav__menu--foused");
setMarker(menu);
}
})
끝!!
marker가 움직이는 내비게이션을 적용한 포트폴리오 페이지가 궁금하시다면
https://soonmac.github.io/portfolio_page/ 이쪽으로 방문해주세요!