neovea
10/6/2017 - 9:12 AM

Make DOM element sticky on scroll

Make DOM element sticky on scroll

/**
 * STICKY FILTERS
 */
class StickyDomScroll {
  constructor () {
    this.selector = null
    this.initialPosition = null
    this.parentDiv = null
    this.newElement = document.createElement('div')
    this.initialPosition = null
  }

  init (selector) {
    this.selector = selector
    this.createElement(this.newElement)

    window.addEventListener('scroll', () => {
      this.initialPosition = this.cumulativeOffset(this.newElement)
      this.handlePosition(this.selector, this.selector.getBoundingClientRect(), this.initialPosition)
      this.defineCreateElementProps(this.newElement, this.selector.offsetHeight)
    })
    window.addEventListener('resize', () => {
      this.initialPosition = this.cumulativeOffset(this.newElement)
      this.handlePosition(this.selector, this.selector.getBoundingClientRect(), this.initialPosition)
      this.defineCreateElementProps(this.newElement, this.selector.offsetHeight)
    })
  }

  cumulativeOffset (element) {
    let top = 0
    do {
      top += element.offsetTop || 0
      element = element.offsetParent
    } while (element)
    return top
  }

  createElement (element) {
    this.parentDiv = this.selector.parentNode
    this.parentDiv.insertBefore(this.newElement, this.selector)
    this.initialPosition = this.cumulativeOffset(element)
    element.style.display = 'none'
  }

  defineCreateElementProps (element, height) {
    element.style.position = 'relative'
    element.style.width = '100%'
    element.style.height = height + 50 + 'px'
  }

  handlePosition (el, currentPosition, initialPosition) {
    if (window.pageYOffset > this.cumulativeOffset(el) - 15 && window.pageYOffset > initialPosition + 15) {
      this.newElement.style.display = 'block'
      el.style.position = 'fixed'
      el.style.top = '-15px'
      el.style.left = currentPosition.left + 'px'
      el.style.width = this.newElement.offsetWidth + 'px'
      el.style.zIndex = '10000'
    } else {
      this.newElement.style.display = 'none'
      el.style.position = 'relative'
      el.style.top = 'inherit'
      el.style.left = 'inherit'
      el.style.right = 'inherit'
      el.style.width = 'inherit'
      el.style.zIndex = 'inherit'
    }
  }
}

export default StickyDomScroll