-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Navigation to the same route fails (anchor, hash) #1668
Comments
I made a workaround by using the method This method takes a success callback (in this case irrelevant) as 2nd and a abort callback as 3rd parameter.
|
@ParachuteKadse Hey mate, I came across the same problem, have you solved this one? If so, would you mind sharing your solution here? Cheers |
savedPosition, is only available if this is a popstate navigation (triggered by the browser's back/forward buttons).
If a falsy value or an empty object is returned, no scrolling will happen. read more he popstate event is only triggered by performing a browser action, such as clicking on the back button (or calling history.back() in JavaScript)... read more savedPosition is meant for save the scroll position object when using back in browser. (AFAIK) official example also suggests use hash for anchor behavior https://github.com/vuejs/vue-router/blob/dev/examples/scroll-behavior/app.js Your expected behavior can be achieved by vue-scroll plugins or use standalone solution using #ids with libraries like jump, zenscroll or other similar libraries |
Possible workaround:
If you want to use it globally, add a function to your Router:
And use it in components with: |
I think it would be fantastic to improve the anchor support. I ran into quite a few questions and issues around this. After reading what everyone has written above I thought I'd paste my solution. I created an anchor-link.vue <template>
<span @click="navigate"><router-link ref="link" :to="to"><slot></slot></router-link></span>
</template>
<script>
export default {
name: 'anchor-link',
props: ['to'],
methods: {
navigate() {
const current = this.$router.currentRoute.fullPath;
const href = this.$refs.link.$el.getAttribute('href');
if (current === href) {
location.href = this.to.hash;
}
}
}
};
</script> router.js excerpt function scrollBehavior(to, from, savedPosition) {
if (to.hash && document.querySelector(to.hash)) {
return { selector: to.hash };
}
if (savedPosition) {
return savedPosition;
}
return false;
}
const router = new Router({ mode: 'history', routes, scrollBehavior }); None of these solutions really work on reloading the page I tried stuff like below but there obviously a race condition, it doesn't really work. Not sure how to come up with a good solution for anchor pages on reload. I feel like we might be competing with the browser's default behaviour. Maybe someone with more experience could lend some insight? mounted() {
const anchor = this.$router.currentRoute.hash;
this.$nextTick(() => {
if (anchor && document.querySelector(anchor)) {
location.href = anchor;
}
});
} |
I gave up on hacks and workarounds. I've tracked this issue down to lines 1916-1923 in
|
The @aldencolerain 's implementation worked perfectly for me mounted() {
const anchor = this.$router.currentRoute.hash;
this.$nextTick(() => {
if (anchor && document.querySelector(anchor)) {
location.href = anchor;
}
});
} |
I went with @gspain solution. I didn't noticed any implications yet (few weeks). |
This worked for me: My Vue Router uses the default mode (hash). The way I see it, because my URLs have 2 hash symbols, the browser behavior of scrolling to a This works whether you inter-site link, navigate directly using the address bar, or refresh the page. router/index.js const router = new Router({
routes: [
// route objects here
// ...
],
scrollBehavior(to, from, savedPosition) {
return {
x: 0,
y: 0,
};
},
}); main.js import Vue from 'vue';
import App from './App';
import router from './router';
Vue.config.productionTip = false;
const fixIdScrolling = {
watch: {
$route(to, from) {
const currentRoute = this.$router.currentRoute;
const idToScrollTo = currentRoute.hash;
this.$nextTick(() => {
if (idToScrollTo && document.querySelector(idToScrollTo)) {
document.querySelector(idToScrollTo).scrollIntoView();
}
});
},
},
};
/* eslint-disable no-new */
new Vue({
mixins: [fixIdScrolling],
el: '#app',
router,
components: {App},
template: '<App/>',
}); |
Thanks heaps this should be implemented |
The changes from @ajb413 mostly work, except when reloading the page or navigating from an external site. Anyone else having those issues? |
@pkkid Having the same issue. Both Personally I'd love to see some functionality that allows me to override that behavior. |
This work with Firefox and mobile(chrome) but does not work with desktop(chrome). |
This is by far the cleanest solution that i have found and it works perfectly.
If you wanted to get fancy and make the scroll smooth, you can even add the following:
|
@gspain @SilverDragon135 Is your solution still working for you? It seems that something has changed since your post. At least it's not working for me. Same behavior. |
It's been almost 4 years. How has this not been fixed yet??? |
My grandfather had said that one day this bug would be fixed but no one believed him. Here we are after ages... |
Already 2023, Any further progress?? |
Version
2.4.2
Reproduction link
https://jsfiddle.net/ParachuteKadse/pL0sehq5/show/
Steps to reproduce
What is expected?
Scroll down to Foo-3, like the first time.
What is actually happening?
Screen stays at the same position and doesn't scroll to Foo-3.
Special notes
You can see the correct URL in the status-bar of your browser
(Tested on Chrome)
The text was updated successfully, but these errors were encountered: