[JS30] - 24) Sticky Nav
approach 1
처음에는 이렇게 접근했다.
const nav = document.querySelector('#main');
console.log(nav)
document.addEventListener('scroll', handleStickyNav);
function handleStickyNav() {
if(nav.offsetTop < window.scrollY) {
console.log('change to sticky nav!')
nav.classList.add('nav-sticky')
} else {
nav.classList.remove('nav-sticky');
}
}
css 'nav-sticky'는 position: fixed;
를 가지고 있다.
이 클래스를 추가해줌으로써 nav의 position을 relative에서 fixed로 바꾸어주어 스크롤할 때 함께 따라올 수 있도록 했다(아래 gif참고)
한 가지 간과했던 게 있었다.
console.log(nav.offsetTop)
을 했을 때 출력결과와 함께 화면을 보자.
위와 같이 처음 네비게이션 바가 sticky하게 바뀌긴 했지만
다시 위로 스크롤했을 때 이미 위로 fix된 nav bar의 offsetTop을 기준으로 scrollY보다 클 때 적용했던 nav-sticky 클래스가 제거 되면서 기존에 있던 위치가 아닌 맨 위에 도달했을 때에서야 제자리로 돌아가게 된다.
즉, nav의 포지션이 바뀌면서 offsetTop이 기존의 nav값이 아닌 0으로 초기화되어 제대로 작동하지 않았다.
approach 2
이를 위해 nav.offsetTop의 초기 값을 별도의 변수에 할당해준 뒤 상수처럼 사용했다.
let navTop = nav.offsetTop; //변수 지정
function handleStickyNav() {
if(navTop< window.scrollY) { //상수값으로 사용
nav.classList.add('nav-sticky')
} else {
nav.classList.remove('nav-sticky');
}
console.log(nav.offsetTop)
}
nav값이 스크롤을 다시 위로 올릴때 제대로 제자리에 돌아가는 것을 확인할 수 있다.
하지만 여전히 한 가지 문제가 있는데, 위gif에서 확인할 수 있듯이 nav bar가 sticky하게 바뀌는 타이밍이 부드럽게 연결되지 않고 뚝뚝 끊기는 느낌이 든다.
approach 3
nav가 sticky하게 바뀌기전
sticky하게 바뀐 직후 이다.
해당 영역에 있는 margin과 padding값 때문인 듯 하다. 자세히 알아보자.
approach 4
알아냈다!
위 이미지와 같이, nav bar가 sticky로 바뀌면서 document의 다른 요소들과는 독립적으로 위쪽에 고정되기 때문에 그 면적이 빠진 공백만큼 nav의 아래 요소가 위로 딸려올라오는 것이 이유였다.
그렇다면 그만큼의 높이를 navbar의 position이 fixed로 바뀔 때 추가해주면 된다.
function handleStickyNav() {
if(navTop< window.scrollY) {
nav.classList.add('nav-sticky');
document.body.style.paddingTop = nav.offsetHeight + 'px';//높이 추가
} else {
nav.classList.remove('nav-sticky');
document.body.style.paddingTop = 0;//높이 제거
}
}
자연스럽고 부드럽게 동작하는 것을 볼 수 있다!
Reference
Author And Source
이 문제에 관하여([JS30] - 24) Sticky Nav), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@gygy/JS30-14-Sticky-Nav저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)