UNPKG

@randstad-design/orbit-multitheme

Version:

multitheme Front-end code based on Randstad Human Forward components

105 lines (88 loc) 2.18 kB
/** * Sticky.js * Script to make a component sticky */ /** * Declare constants */ const attributeBase = 'data-rs-sticky'; export class Sticky { constructor(element) { this.element = element; this.addEventHandlers(); this.makeElementSticky(); this.stickyHeight = this.element.offsetHeight; } /** * Declare attribute constants */ get attributes() { return {}; } /** * Declare classes */ get classes() { return { sticky: this.element.dataset.rsSticky ? this.element.dataset.rsSticky : 'is-sticky' }; } /** * Add event handlers */ addEventHandlers() { window.addEventListener('resize', () => { this.makeElementSticky(); }); } makeElementSticky() { const elementIsVisible = getComputedStyle(this.element).getPropertyValue('display') !== 'none'; if (elementIsVisible) { const elementPos = this.element.offsetTop; const windowScrollStartPos = window.scrollY; if (windowScrollStartPos > elementPos) { this.element.classList.add(this.classes.sticky); this.addExtraSpacingToNextElement(); } window.addEventListener('scroll', () => { const windowScrollPos = window.scrollY; if (windowScrollPos > elementPos) { this.element.classList.add(this.classes.sticky); this.addExtraSpacingToNextElement(); } else { this.element.classList.remove(this.classes.sticky); this.removeExtraSpacingNextElement(); } }); } } addExtraSpacingToNextElement() { const nextElement = this.next(this.element); nextElement.setAttribute( 'style', `top: ${this.stickyHeight}px; position: relative;` ); } removeExtraSpacingNextElement() { const nextElement = this.next(this.element); nextElement.removeAttribute('style'); } /* * Function to get the next elements node instead of text node */ next(elem) { do { elem = elem.nextSibling; } while (elem && elem.nodeType !== 1); return elem; } /** * Get selector */ static getSelector() { return `[${attributeBase}]`; } }