console
document.addEventListener('DOMContentLoaded', function () {
const sidebar = document.querySelector('#sidebar');
const first = document.querySelector('#first');
const last = document.querySelector('#last');
initFixedSidebar(sidebar,first,last)
});
function initFixedSidebar (sideBar,first,last){
let isOverTop, isOverBottom;
const FIXED_VALUE_TOP = 8;
const FIXED_VALUE_BOTTOM = 8;
const domObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.target == first) {
isOverTop = entry.isIntersecting
if (entry.isIntersecting) {
isOverBottom = false
}
}
if (entry.target == last) {
isOverBottom = entry.isIntersecting
if (entry.isIntersecting) {
isOverTop = false
}
}
});
}, { root: null, rootMargin: '0px', threshold: [1] });
domObserver.observe(first);
domObserver.observe(last);
setTimeout(() => {
isOverBottom = false
isOverTop = true
}, 100);
let lastScrollTop = window.pageYOffset || document.documentElement.scrollTop;
window.addEventListener('scroll', () => {
const currentScrollPosition = window.pageYOffset;
const scrollDistance = currentScrollPosition - lastScrollTop;
if (currentScrollPosition >= lastScrollTop) {
if (isOverBottom) {
sidebar.style.position = 'fixed';
sidebar.style.bottom = FIXED_VALUE_BOTTOM+'px';
sidebar.style.top = '';
} else {
const bottom = window.getComputedStyle(sidebar).getPropertyValue('bottom');
sidebar.style.position = 'fixed';
sidebar.style.top = '';
sidebar.style.bottom = `calc( ${scrollDistance}px + ${bottom || 0} )`;
}
} else if (currentScrollPosition <= lastScrollTop) {
if (isOverTop) {
sidebar.style.position = 'fixed';
sidebar.style.top = FIXED_VALUE_TOP+'px';
sidebar.style.bottom = '';
} else {
const bottom = window.getComputedStyle(sidebar).getPropertyValue('bottom');
sidebar.style.position = 'fixed';
sidebar.style.bottom = `calc( ${bottom} + ${scrollDistance}px )`;
sidebar.style.top = '';
}
}
lastScrollTop = currentScrollPosition;
});
}
<div id='body'>
<div id='content'>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="sidebar-perch"></div>
<div id='sidebar'>
<div class="section" id="first"></div>
<div class="section"></div>
<div class="section"></div>
<div class="section"></div>
<div class="section" id="last"></div>
</div>
</div>
#body {
display: flex;
justify-content: center;
align-items: flex-start;
position: relative;
}
#content {
width: 50%;
background-color: white;
}
#sidebar {
position: fixed;
right: 10%;
width: 25%;
height: auto;
background-color: white;
}
.sidebar-perch{
width: 25%;
}
.item {
width: 80%;
height: 320px;
margin: 20px;
background-color: darkmagenta;
}
.section {
width: 80%;
height: 280px;
margin: 20px;
background-color: sienna;
}