Wesbos - Sticky Nav


완성본 예시

반응형 웹사이트를 만드는 데에 굉장히 유용하게 쓰일 것 같은 챕터였다.
많은 비즈니스 웹사이트들이 이러한 기능들을 활용하고 있는 것 같다.


로직

  1. const와 스크롤 이벤트에 반응하는 함수 만들기
  2. nav바의 offsetTop값 활용하기
  3. 부자연스러운 부분 해결하며 완성도 높이기

const 선언과 Scroll 이벤트

💡 nav에 대한 선언을 하고, Scroll이벤트를 수신할 엘리먼트와 그에 따른 함수를 생성해주자.

1
2
3
4
5
6
7
const nav = document.querySelector('#main');

function fixNav() {
console.log(nav); // 찍어보기
}

window.addEventListener('scroll', fixNav);

콘솔로 확인


offsetTop과 scrollY의 활용

스크롤 슬라이드인 챕터에서 사용했던 논리와 유사하다고 생각하면 된다.

1
2
3
4
5
6
7
8
function fixNav() {
console.log(nav.offsetTop);
if (window.scrollY >= nav.offsetTop) {
document.body.classList.add('fixed-nav');
} else {
document.body.classList.remove('fixed-nav');
}
}

‼️ 하지만…. fixed-nav 클래스가 remove되지 않는 현상이 발생한다.

문제발생

body태그

❓ 뭐가 문제일까…. 고민을 해보다 console.log(nav.offsetTop)로 찍어보니
if문 실행 이후 -> 보이는 바와 같이 offsetTop의 값이 0으로 변해버려 else문이 실행이 되지 않았던 것이 문제였다.

함수 밖에서 let을 통해 nav.offsetTop의 값을 선언해주면 되는 문제였다.

1
2
3
4
5
6
7
8
9
10
let navTop = nav.offsetTop; // fixNav에 의해 nav가 fixed 되어도 offsetTop값은 초기의 값으로 고정된다.

function fixNav() {
console.log(navTop);
if (window.scrollY >= navTop) {
document.body.classList.add('fixed-nav');
} else {
document.body.classList.remove('fixed-nav');
}
}

부자연스러운 transition

fixNav() 함수에 의해 position이 fixed될 때 트랜지션이 부자연스럽게 뚝뚝 끊기는 현상이 발생한다

body의 height가 정확히 nav의 height만큼 늘었다 줄었다 하는 것을 발견했다.

height의 변화에 주목

이는 nav의 포지션이 fixed 되면서
nav의 height값 만큼 body의 상단을 잡아먹었기 때문이다.

그럼 nav의 height값 만큼 padding-top을 줘서

fixNav() 가 실행될 때 body 내에 존재하는 엘리먼트들을 아래로 밀어내주면 되지 않을까

1
2
3
4
5
6
7
8
9
function fixNav() {
if (window.scrollY >= navTop) {
document.body.style.paddingTop = nav.offsetHeight + 'px';
document.body.classList.add('fixed-nav');
} else {
document.body.classList.remove('fixed-nav');
document.body.style.paddingTop = 0;
}
}

최종 완성 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const nav = document.querySelector('#main');
let navTop = nav.offsetTop;

function fixNav() {
console.log(navTop);
if (window.scrollY >= navTop) {
document.body.style.paddingTop = nav.offsetHeight + 'px';
document.body.classList.add('fixed-nav');
} else {
document.body.classList.remove('fixed-nav');
document.body.style.paddingTop = 0;
}
}

window.addEventListener('scroll', fixNav);

Author

Hoonjoo

Posted on

2022-01-05

Updated on

2022-02-07

Licensed under

Comments