Skip to content

Instantly share code, notes, and snippets.

@nathanlogan
Created November 15, 2016 19:29
Show Gist options
  • Save nathanlogan/941f296aee7f3fa59689666382101d9f to your computer and use it in GitHub Desktop.
Save nathanlogan/941f296aee7f3fa59689666382101d9f to your computer and use it in GitHub Desktop.
Emulate URL anchor page scroll functionality in a React component
import React, { Component } from 'react'
class MyTopLevelComponent extends Component {
componentDidMount () {
this.scrollToHashId()
}
componentDidUpdate () {
this.scrollToHashId()
}
// emulate URL anchor page scroll functionality
scrollToHashId () {
const removeHash = this.removeHash
// get URL hash (minus the hash mark)
const hash = window.location.hash.substring(1)
// if there's a hash, scroll to that ID
if (hash && hash.length) {
// setTimeout and requestAnimationFrame help ensure a true DOM repaint/reflow before we try to scroll
// - reference: http://stackoverflow.com/a/34999925
setTimeout(
window.requestAnimationFrame(function () {
const el = document.getElementById(hash)
el.scrollIntoView()
// clean up the hash, so we don't scroll on every prop update
removeHash()
}),
0
)
}
}
// borrowed from http://stackoverflow.com/questions/1397329/how-to-remove-the-hash-from-window-location-with-javascript-without-page-refresh/5298684#5298684
removeHash () {
const loc = window.location
const hist = window.history
// use modern browser history API
if (hist && 'pushState' in hist) {
hist.replaceState('', document.title, loc.pathname + loc.search)
// fallback for older browsers
} else {
// prevent scrolling by storing the page's current scroll offset
const scrollV = document.body.scrollTop
const scrollH = document.body.scrollLeft
loc.hash = ''
// restore the scroll offset, should be flicker free
document.body.scrollTop = scrollV
document.body.scrollLeft = scrollH
}
}
render () {
<p>Render here...</p>
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment