Created
April 13, 2016 21:06
-
-
Save jondkoon/e81c956674655d3cae625e985f749d81 to your computer and use it in GitHub Desktop.
Enhanced Standard Scroll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { canUseDOM } from 'exenv'; | |
import { readState } from 'history/lib/DOMStateStorage' | |
import requestAnimationFrame from 'dom-helpers/util/requestAnimationFrame' | |
import useStandardScroll from './useStandardScroll'; | |
export default function useScroll(createHistory) { | |
const positionByPath = {}; | |
const getState = (location) => { | |
return { | |
...(location && location.state || {}), | |
...(location && location.key && readState(location.key) || {}) | |
}; | |
} | |
const getScrollPosition = (oldLocation, newLocation) => { | |
const previousPath = oldLocation && oldLocation.pathname; | |
const previousState = getState(oldLocation); | |
const previousScrollPosition = previousState.scrollPosition; | |
if (previousScrollPosition) { | |
positionByPath[previousPath] = previousScrollPosition; | |
} | |
const newPath = newLocation && newLocation.pathname; | |
const newState = getState(newLocation); | |
const positionFromPath = newState.restoreScroll && positionByPath[newPath]; | |
const positionFromState = newState.scrollPosition; | |
const ignoreScroll = newState.ignoreScroll; | |
const defaultPosition = [0, 0]; | |
if (ignoreScroll) { | |
return false; | |
} else if (previousPath === newPath) { | |
// Scroll to top if you navigate to the route you are already on | |
return defaultPosition; | |
} else { | |
return positionFromPath || positionFromState || defaultPosition; | |
} | |
} | |
return useStandardScroll(createHistory)({ | |
shouldUpdateScroll: (oldLocation, newLocation) => { | |
const scrollPosition = getScrollPosition(oldLocation, newLocation); | |
if (scrollPosition && canUseDOM) { | |
requestAnimationFrame(() => { | |
const [x, y] = scrollPosition; | |
window.scrollTo(x, y); | |
}); | |
} | |
return false; | |
} | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment