9

I have a small Vue.js SPA with the following router configuration, taken from the docs:

export default new VueRouter({
    routes, // defined above...

    mode: 'history',

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

Consider a link on the homepage:

<router-link to="#services">Services</router-link>

It jumps to the anchor element <div id="services">...</div> as expected. However, when you activate the link, then scroll away from #services, and refresh the page, you will not be brought back to #services. You will stay in the same position where you left off, even though the URL would still have the hash in it (e.g. in the form of app.dev/#services).

How can I configure the router so that on page load, it bring the user to the anchor element, given that the URL contains its hash (and, well, that hash corresponds to a valid existing element)?

Alex
  • 2,989
  • 3
  • 27
  • 52
  • It's a browser feature if it remembers where you left off, overriding the (desired) default behavior. To make sure, does it work as expected when the browser history is set aside (i.e., using a fresh incognito/private-browsing window)? You of course can always trigger a router-link "click" programmatically by referencing then .click()ing one after the page is ready. – Rashad Saleh Sep 05 '17 at 19:38

1 Answers1

7

I had the same problem but also wanted to have an animated scroll to the hash. I was able to check off both features with vue-scrollto. https://github.com/rigor789/vue-scrollto

Something like this should work.

// import
import VueScrollTo from 'vue-scrollto';

//...

scrollBehavior(to, from, savedPosition) {
    if (to.hash) {
        VueScrollTo.scrollTo(to.hash, 700);
        return { selector: to.hash }
    } else if (savedPosition) {
        return savedPosition;
    } else {
        return { x: 0, y: 0 }
    }
}

That way, it always animates to the hash. If you don't want to animate, use 0 as the time instead of 700. If you don't like using that module, you can manually jump to the anchor via regular javascript using the techniques described here

ProblemsOfSumit
  • 14,940
  • 9
  • 43
  • 60