Skip to content

Instantly share code, notes, and snippets.

@souporserious
Created October 17, 2017 23:27
Show Gist options
  • Save souporserious/e09e942d4ad0f13d98ca6120141d103b to your computer and use it in GitHub Desktop.
Save souporserious/e09e942d4ad0f13d98ca6120141d103b to your computer and use it in GitHub Desktop.
function getClosestScrollParent(node) {
const rootNode = typeof document === 'undefined' ? null : document.body
if (node !== null && node !== rootNode) {
if (node.scrollHeight > node.clientHeight) {
return node
} else {
return getClosestScrollParent(node.parentNode)
}
} else {
return null
}
}
class Sticky extends Component {
state = {
stuck: false,
}
componentDidMount() {
this.placeholderHeight = this.node.offsetHeight
this.stickPoint = this.node.offsetTop
this.scrollParent = getClosestScrollParent(this.node) || window
this.scrollParent.addEventListener('scroll', this.updateStickyState)
this.updateStickyState()
}
componentWillUnmount() {
this.scrollParent.removeEventListener('scroll', this.updateStickyState)
}
setStickyNode = node => {
this.node = node
}
updateStickyState = e => {
const offset =
this.scrollParent === window
? window.pageYOffset
: this.scrollParent.scrollTop
const distance = this.node.offsetTop - offset
this.setState(state => {
const newState = {}
if (distance <= 0 && !state.stuck) {
newState.stuck = true
} else if (state.stuck && offset <= this.stickPoint) {
newState.stuck = false
}
return newState
})
}
render() {
return this.props.children({
stickyRef: this.setStickyNode,
placeholderHeight: this.placeholderHeight,
stuck: this.state.stuck,
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment