Vue.js scroll to top of new page route after setTimeout

走远了吗. 提交于 2021-01-20 17:43:27

问题


I have a page transition that doesn't work nicely when the scroll to the top of a new route is instant. I'd like to wait 100ms before it automatically scrolls to the top. The following code doesn't end up scrolling at all. Is there a way to do this?

export default new Router({
    mode: 'history',
    routes: [
        {
            path: '/',
            name: 'Home',
            component: Home
        }
    ],
    scrollBehavior (to, from, savedPosition) {
        setTimeout(() => {
            return { x: 0, y: 0 }
        }, 100);
    }
})

回答1:


This is natively supported by Vue now, use scrollBehaviour, like this:

export default new Router({
  scrollBehavior() {
    return { x: 0, y: 0 };
  },
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home
    }
  ],
  mode: 'history'
});

More here.




回答2:


The other answers fail to handle edge cases such as:

  1. Saved Position - The saved position occurs when the user clicks the back or forward positions. We want to maintain the location the user was looking at.
  2. Hash Links - E.g. http://example.com/foo#bar should navigate to the element on the page with an id of bar.
  3. Finally, in all other cases we can navigate to the top of the page.

Here is the sample code that handles all of the above:

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes,
  scrollBehavior: (to, from, savedPosition) => {
    if (savedPosition) {
      return savedPosition;
    } else if (to.hash) {
      return {
        selector: to.hash
      };
    } else {
      return { x: 0, y: 0 };
    }
  }
});



回答3:


If you want this to happen on every route, you can do so in the before hook in the router:

const router = new VueRouter({ ... })

router.beforeEach(function (to, from, next) { 
    setTimeout(() => {
        window.scrollTo(0, 0);
    }, 100);
    next();
});

If you are on an older version of vue-router, use:

router.beforeEach(function (transition) { 
    setTimeout(() => {
        window.scrollTo(0, 0);
    }, 100);
    transition.next();
});



回答4:


When using client-side routing, we may want to scroll to top when navigating to a new route, or preserve the scrolling position of history entries just like real page reload does. vue-router allows you to achieve these and even better, allows you to completely customize the scroll behavior on route navigation.

Note: this feature only works if the browser supports history.pushState.

scrollBehavior (to, from, savedPosition) {
  return { x: 0, y: 0 }
}

With Saved Position:

scrollBehavior (to, from, savedPosition) {
  if (savedPosition) {
    return savedPosition
  } else {
    return { x: 0, y: 0 }
  }
}

For more information




回答5:


This is probably not the best way, but adding

document.body.scrollTop = document.documentElement.scrollTop = 0;

in a route's core component's (in this case, Home) mounted() function achieves what I want.




回答6:


If you want to wait a long time use Async Scrolling of scrollBehaviour, like this:

export default new Router({
  scrollBehavior() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve({ x: 0, y: 0 })
      }, 100)
    })
  },
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home
    }
  ],
  mode: 'history'
});

More here.



来源:https://stackoverflow.com/questions/42538449/vue-js-scroll-to-top-of-new-page-route-after-settimeout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!