12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- import { getMatchedComponents, setScrollRestoration } from './utils'
- if (process.client) {
- if ('scrollRestoration' in window.history) {
- setScrollRestoration('manual')
- // reset scrollRestoration to auto when leaving page, allowing page reload
- // and back-navigation from other pages to use the browser to restore the
- // scrolling position.
- window.addEventListener('beforeunload', () => {
- setScrollRestoration('auto')
- })
- // Setting scrollRestoration to manual again when returning to this page.
- window.addEventListener('load', () => {
- setScrollRestoration('manual')
- })
- }
- }
- function shouldScrollToTop(route) {
- const Pages = getMatchedComponents(route)
- if (Pages.length === 1) {
- const { options = {} } = Pages[0]
- return options.scrollToTop !== false
- }
- return Pages.some(({ options }) => options && options.scrollToTop)
- }
- export default function (to, from, savedPosition) {
- // If the returned position is falsy or an empty object, will retain current scroll position
- let position = false
- const isRouteChanged = to !== from
- // savedPosition is only available for popstate navigations (back button)
- if (savedPosition) {
- position = savedPosition
- } else if (isRouteChanged && shouldScrollToTop(to)) {
- position = { x: 0, y: 0 }
- }
- const nuxt = window.$nuxt
- if (
- // Initial load (vuejs/vue-router#3199)
- !isRouteChanged ||
- // Route hash changes
- (to.path === from.path && to.hash !== from.hash)
- ) {
- nuxt.$nextTick(() => nuxt.$emit('triggerScroll'))
- }
- return new Promise((resolve) => {
- // wait for the out transition to complete (if necessary)
- nuxt.$once('triggerScroll', () => {
- // coords will be used if no selector is provided,
- // or if the selector didn't match any element.
- if (to.hash) {
- let hash = to.hash
- // CSS.escape() is not supported with IE and Edge.
- if (typeof window.CSS !== 'undefined' && typeof window.CSS.escape !== 'undefined') {
- hash = '#' + window.CSS.escape(hash.substr(1))
- }
- try {
- if (document.querySelector(hash)) {
- // scroll to anchor by returning the selector
- position = { selector: hash }
- }
- } catch (e) {
- console.warn('Failed to save scroll position. Please add CSS.escape() polyfill (https://github.com/mathiasbynens/CSS.escape).')
- }
- }
- resolve(position)
- })
- })
- }
|