Js
원페이지 스크롤
by 영감은어디에
2025. 3. 3.
<nav>
<a href="#section1" class="active">섹션 1</a>
<a href="#section2">섹션 2</a>
<a href="#section3">섹션 3</a>
<a href="#section4">섹션 4</a>
<a href="#section5">섹션 5</a>
</nav>
<section id="section1" style="height: 100vh; background: lightgray;">섹션 1</section>
<section id="section2" style="height: 100vh; background: lightblue;">섹션 2</section>
<section id="section3" style="height: 100vh; background: lightgreen;">섹션 3</section>
<section id="section4" style="height: 100vh; background: lightcoral;">섹션 4</section>
<section id="section5" style="height: 100vh; background: lightsalmon;">섹션 5</section>
const navLinks = document.querySelectorAll("nav a");
const sections = document.querySelectorAll("section");
navLinks.forEach(link => {
link.addEventListener("click", function(event) {
event.preventDefault();
isScrolling = true;
navLinks.forEach(a => a.classList.remove("active"));
this.classList.add("active");
const targetId = this.getAttribute("href").substring(1);
const target = document.getElementById(targetId);
const offset = target.offsetTop;
const startPosition = window.scrollY;
const distance = offset - startPosition;
const duration = 600;
let startTime = null;
function animation(currentTime) {
if (startTime === null) startTime = currentTime;
const timeElapsed = currentTime - startTime;
const progress = Math.min(timeElapsed / duration, 1);
const easing = progress < 0.5 ? 2 * progress ** 2 : 1 - Math.pow(-2 * progress + 2, 2) / 2;
window.scrollTo(0, startPosition + distance * easing);
if (timeElapsed < duration) {
requestAnimationFrame(animation);
} else {
isScrolling = false;
}
}
requestAnimationFrame(animation);
});
});
let isScrolling = false;
function updateActiveNav() {
if (isScrolling) return;
let scrollPosition = window.scrollY;
sections.forEach((section, index) => {
const sectionTop = section.offsetTop;
const sectionHeight = section.offsetHeight;
if (scrollPosition >= sectionTop - sectionHeight / 2 && scrollPosition < sectionTop + sectionHeight / 2) {
navLinks.forEach(a => a.classList.remove("active"));
navLinks[index].classList.add("active");
}
});
}
window.addEventListener("scroll", updateActiveNav);