minor: Improve scrollBehavior to work with transitions, resolve #1376, thanks to @homerjam

This commit is contained in:
Sébastien Chopin 2018-01-31 16:13:28 +01:00
parent 9818116a52
commit 358e2f32fd
2 changed files with 39 additions and 20 deletions

View File

@ -29,6 +29,12 @@ export default {
listeners[key] = transition[key].bind(_parent) listeners[key] = transition[key].bind(_parent)
} }
}) })
// Add triggerScroll event on beforeEnter (fix #1376)
let beforeEnter = listeners.beforeEnter
listeners.beforeEnter = (el) => {
window.$nuxt.$emit('triggerScroll')
if (beforeEnter) return beforeEnter.call(_parent, el)
}
let routerView = [ let routerView = [
h('router-view', data) h('router-view', data)

View File

@ -26,27 +26,40 @@ uniqBy(_components, '_name').forEach((route) => { %>const <%= route._name %> = (
<% if (router.scrollBehavior) { %> <% if (router.scrollBehavior) { %>
const scrollBehavior = <%= serialize(router.scrollBehavior).replace('scrollBehavior(', 'function(').replace('function function', 'function') %> const scrollBehavior = <%= serialize(router.scrollBehavior).replace('scrollBehavior(', 'function(').replace('function function', 'function') %>
<% } else { %> <% } else { %>
const scrollBehavior = (to, from, savedPosition) => { if (process.client) {
// SavedPosition is only available for popstate navigations. window.history.scrollRestoration = 'manual'
if (savedPosition) { }
return savedPosition const scrollBehavior = function (to, from, savedPosition) {
} else { // if the returned position is falsy or an empty object,
let position = {} // will retain current scroll position.
// If no children detected let position = false
// if no children detected
if (to.matched.length < 2) { if (to.matched.length < 2) {
// Scroll to the top of the page // scroll to the top of the page
position = { x: 0, y: 0 }
} else if (to.matched.some((r) => r.components.default.options.scrollToTop)) {
// if one of the children has scrollToTop option set to true
position = { x: 0, y: 0 } position = { x: 0, y: 0 }
} }
else if (to.matched.some((r) => r.components.default.options.scrollToTop)) {
// If one of the children has scrollToTop option set to true // savedPosition is only available for popstate navigations (back button)
position = { x: 0, y: 0 } if (savedPosition) {
position = savedPosition
} }
// If link has anchor, scroll to anchor by returning the selector
if (to.hash) { return new Promise(resolve => {
// wait for the out transition to complete (if necessary)
window.$nuxt.$once('triggerScroll', () => {
// coords will be used if no selector is provided,
// or if the selector didn't match any element.
if (to.hash && document.querySelector(to.hash)) {
// scroll to anchor by returning the selector
position = { selector: to.hash } position = { selector: to.hash }
} }
return position resolve(position)
} })
})
} }
<% } %> <% } %>