My objective was to create a block which remains as a sticky block in the sidebar of the page when the window is scrolled. Also the blocks below the sticky block need to move along with it. The sticky blocks should stop moving once they reach the end of sidebar and no longer should move when the page is scrolled.
The basic script I got it from here (andrewhenderson.me), which I modified for my purpose. I needed additional features, such as the blocks (blocks may vary on different pages) which appear below the sticky block should move along with it when scrolled. Also the sticky blocks should stop moving when they reach the end of the sidebar, i.e. it should not move over the bottom footer content. To see what I tried to achieve see the demo.
The html structure looks like this.
The modified script is as below:
(Edit: New updated code)
jQuery(document).ready(function($) {
if (!!$('.sticky-block').offset()) { // Check if sticky block element exists,
// Need to add a wrapping for sticky block and blocks below it.
var stickyIndex = $('.sticky-block').index(); // Get index of sticky block.
$('.sidebar .block').slice(stickyIndex).wrapAll('<div class="sticky-wrap"></div>'); // Add a wrap for sticky block and blocks below it.
// To avoid width of sticky wrapper expand when position fixed is applied when scrolling a width need to defined.
var stickyWidth = $(".sidebar").innerWidth(); // Get width of the sidebar.
$('.sidebar .sticky-wrap').css({ 'width': stickyWidth}); // Apply the width of the sidebar to the sticky wrapper.
// When end of sidebar is reached the sticky wrapper should be applied position absolute in relative to sidebar.
// So the height of sidebar should be equal to the right content if it is lengthier.
var sidebarHeight = $(".sidebar").height();
var contentHeight = $(".content").height();
if(contentHeight > sidebarHeight){
sidebarHeight = contentHeight;
$(".sidebar").height(sidebarHeight);
}
// To get the bottom position where the sticky wrapper should stop moving when scrolled.
// Sticky blocks should should not scroll over footer content.
var sidebarTop = $('.sidebar').offset().top; // Get sidebar top position.
var stickyHeight = $('.sidebar .sticky-wrap').height(); // Get the height of the sticky wrapper.
var maxScroll = sidebarTop + (sidebarHeight - stickyHeight); // Max point where the scrolling should end.
var stickyTop = $('.sticky-block').offset().top; // Get the top position of the sticky block.
$(window).scroll(function(){ // Scroll event.
var windowTop = $(window).scrollTop(); // Current scroll top position of window.
if (stickyTop < windowTop && maxScroll > windowTop){ // When scrolling fix the position of block.
$('.sidebar').css('position','static');
$('.sticky-wrap').css({ 'position': 'fixed', 'top': '10px', 'z-index': 900 });
}
else if (maxScroll < windowTop){ // When scroll reaches end of sidebar sticky elements should stay at the end of sidebar.
$('.sidebar').css('position','relative');
$('.sticky-wrap').css({ 'position': 'absolute', 'top': 'auto', 'bottom': 0 });
}
else { // When sidebar top reaches change everything back to normal.
$('.sidebar').css('position','static');
$('.sticky-wrap').css('position','static');
}
});
}
});
Edit: New updated code here