Как я могу установить положение элемента между фиксированным и относительным при прокрутке в зависимости от условий?
<div id="wrapper">
<div id="left-panel"></div>
<div id="long-right-panel></div>
</div>
<footer></footer>
При прокрутке я сталкиваюсь с проблемой, когда #wrapper
верхняя позиция <= 0 и когда footer
верхняя позиция вычитается из #left-panel
нижняя позиция>=0, я бы хотел #left-panel
иметь фиксированную позицию стиля. Иначе оно должно иметь положение родственника.
Я сталкиваюсь с проблемой, когда после выполнения вышеуказанных условий # левая панель переключается между позицией относительной и фиксированной.
Вот код для пояснения:
// creates event listener
window.addEventListener('scroll', handleScroll);
// get DOM elements outside of scroll event
const wrapperRect = document.getElementById('wrapper').getBoundingClientRect();
const leftPanel = document.getElementById('left-panel');
const leftPanelRect = leftPanel.getBoundingClientRect();
const rightPanel = document.getElementById('long-right-panel');
const rightPanelRect = rightPanel.getBoundingClientRect();
const footerRect = document.querySelector('footer').getBoundingClientRect();
function handleScroll () {
/* if the #wrapper has scrolled past the top of the viewport and the space between the top of the footer and the bottom of the #left-panel is greater than 0, set #left-panel to position fixed */
if (wrapperRect.top <= 0 && (footerRect.top - leftPanelRect.bottom) > 0) {
leftPanel.setAttribute("style", "position: fixed; top: 3rem;");
rightPanel.setAttribute("style", "margin-left: 45%;");
}
/* else set the #left-panel position to relative */
else {
leftPanel.setAttribute("style", "position: relative;");
rightPanel.setAttribute("style", "");
}
}
Код работает, за исключением того, что мне нужен какой-то флаг или средство для его устранения, потому что в том виде, в каком он есть, когда условия истинны, они исправлены, но когда они ложны, #left-panel
возвращается в исходное положение и #wrapper
верх < 0, а пространство между footerRect.top
а также leftPanelRect.bottom
is > 0 и изменяет его на фиксированный... затем прокрутка изменяется обратно на относительную... это вызывает скачки и мерцание.
Любой совет, как исправить?
1 ответ
Ваш код на самом деле работает нормально, я протестировал его с последним Chrome на Windows 8.1. Но если вы имеете в виду, что страница переходит при первой прокрутке, попробуйте добавить
window.addEventListener('load', handleScroll);
поверх скрипта - чтобы проверить условия и установить стили при загрузке страницы:
<style>
#wrapper {
height: 200vh;
width: 100%;
}
#left-panel {
background-color: #f90;
height: 200px;
width: 45%;
}
#long-right-panel {
background-color: #f09;
height: 500px;
margin-top: 3rem;
width: 55%;
}
#footer {
background-color: #9f9;
height: 100px;
width: 100%;
}
</style>
<div id="wrapper">
<div id="left-panel"></div>
<div id="long-right-panel"></div>
</div>
<footer id="footer"></footer>
<script>
// creates event listener
window.addEventListener('load', handleScroll);
window.addEventListener('scroll', handleScroll);
// get DOM elements outside of scroll event
const wrapperRect = document.getElementById('wrapper').getBoundingClientRect();
const leftPanel = document.getElementById('left-panel');
const leftPanelRect = leftPanel.getBoundingClientRect();
const rightPanel = document.getElementById('long-right-panel');
const rightPanelRect = rightPanel.getBoundingClientRect();
const footerRect = document.querySelector('footer').getBoundingClientRect();
function handleScroll () {
/* if the #wrapper has scrolled past the top of the viewport
and the space between the top of the footer and the bottom of the #left-panel
is greater than 0, set #left-panel to position fixed */
if (wrapperRect.top <= 0 && (footerRect.top - leftPanelRect.bottom) > 0) {
leftPanel.setAttribute("style", "position: fixed; top: 3rem;");
rightPanel.setAttribute("style", "margin-left: 45%;");
}
/* else set the #left-panel position to relative */
else {
leftPanel.setAttribute("style", "position: relative;");
rightPanel.setAttribute("style", "");
}
}
</script>
https://codepen.io/svitch/pen/yzEzmz
Обычно скрипты липкой панели имеют три условия:
- panel.top
- panel.top> wrapper.top && panel.bottom
- panel.bottom> wrapper.bottom
- panel.top> wrapper.top && panel.bottom
В этом случае ваша панель будет зависать, когда обертка выходит за пределы экрана, и отклеиваться, когда панель больше не нужна.