content/frontend/default/directives/stick_to_footer.js (33 lines of code) (raw):

const NAV_INLINE_BREAKPOINT = 1100; const NAV_TOP_MARGIN = 55; const isTouchingBottom = (height, offsetHeight) => { if (window.innerWidth < NAV_INLINE_BREAKPOINT) { return false; } return offsetHeight <= window.scrollY + height; }; const getTopOffset = (height, offsetHeight) => { if (isTouchingBottom(height, offsetHeight)) { return offsetHeight - (window.scrollY + height); } return 0; }; export const StickToFooter = { bind(el, { value }) { let contentHeight; const mainEl = document.querySelector(value); el.$_stickToFooter_listener = () => { if (!contentHeight) { contentHeight = el.getBoundingClientRect().height + NAV_TOP_MARGIN; } const { offsetHeight } = mainEl; const topOffset = getTopOffset(contentHeight, offsetHeight); el.style.top = topOffset < 0 ? `${topOffset}px` : ''; }; // When we scroll down to the bottom, we don't want the footer covering // the TOC list (sticky behavior) document.addEventListener('scroll', el.$_stickToFooter_listener, { passive: true }); }, unbind(el) { el.style.top = ''; document.removeEventListener('scroll', el.$_stickToFooter_listener); }, };