Изменяется window.scroll при добавлении элемента
Пытаюсь реализовать меню, которое будет приклеено к верхней части экрана, если пользователь прокрутил страницу вниз. Высота меню - 74px;
componentDidMount() {
window.addEventListener('scroll', () => {
console.log(window.scrollY);
if (window.scrollY >= 700) {
this.setState({ className: 'navbar fixed' });
} else {
this.setState({ className: 'navbar' });
}
});
}
Когда прокрутка доходит до window.scrollY = 700, к меню добавляется класс fixed, оно отображается, но window.scrollY становится равен 626 (700 минус высота меню(74)), и меню начинает очень быстро появляться и исчезать, console.log(window.scrollY) попеременно отображает то 700 то 626.
Если прокрутить ещё ниже - проблема исчезает, и меню стабильно отображается и не "скачет"
Ответы (2 шт):
Присвойте меню изначально position: absolute. Тогда его высота не будет учитываться. А контент сдвиньте вниз на значение равное высоте меню. Посмотрите пример.
const componentDidMount = () => {
window.addEventListener('scroll', () => {
const nav = document.querySelector("nav");
if (window.scrollY >= 700) {
nav.classList.add("fixed");
} else {
nav.classList.remove("fixed");
}
});
}
componentDidMount();
body {
margin: 0;
}
main {
height: 1000vh;
background: green;
margin-top: 74px;
}
nav {
width: 100%;
height: 74px;
background: red;
position: absolute;
top: 0;
}
.fixed {
position: fixed;
}
<nav></nav>
<main></main>
В 2020 году можно смело использовать position:sticky :)
Ваш ответ натолкнул меня на другое решение: Записать в html второе, такое же меню, но изначально задать ему класс hide с display:none, а при прокрутке window.scrollY >= 700, через стейт менять класс второго меню на fixed
Можно поступить проще - добавить дополнительную обертку для меню и задать ей такую же высоту как и меню. В этом случае, меню будет менять position между значениями static/fixed, а обертка всегда будет static и при этом иметь высоту меню. Это предотвратит "скачки" при скроллинге