-
-
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
pass on extra arguments to scrollTo
to enable smooth scrolling with behaviour
#2069
Comments
That's already possible with |
That has nothing to do with what I'm saying. Giving a In this file: https://github.com/vuejs/vue-router/blob/dev/src/util/scroll.js I'd like to change line 126 from
to something like
Obviously this would need to be parametrized. This would apply a smooth scrolling in modern browser and apply a normal scroll like right now in older ones. If you add the polyfill I said before then it smootly scrolls on every device. |
Aaah, sorry, didn't understand it correctly. |
Let me add this links I found. It's actually a CSS Property specification: Firefox: https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior |
In the future I think it will be safe to pass any extra parameter to the |
Just looked at the source code of the polyfill I mentioned. He uses this function, because as I said, this scrollBehaviour is actually a CSS prop. https://github.com/iamdustan/smoothscroll/blob/master/src/smoothscroll.js
Should be feasable, I'll check this once I get home and can use IE7 :D |
the last browser supported is ie9 lol |
This starts to look good, could you maybe reopen this issue? IE9 -> scrollBehavior' in document.documentElement.style -> false; But that doesn't really matter as scroll() is not available on IE9 anyway. I'd love to help implement this one, but so far i've never commited anything to a public repo. |
scrollTo
to enable smooth scrolling with behaviour
Ok, as long as the overhead is small enough to be worth adding 😉 |
Hey guys, follow the solution for any decent browser:
|
Please be advised that this will throw an error when the hash starts with a number or the selector does not exists. This can be fixed by using scrollBehavior(to) {
if (to.hash) {
const element = document.getElementById(to.hash.slice(1));
if (element) {
return window.scrollTo({
top: element.offsetTop,
behavior: 'smooth'
});
}
}
return window.scrollTo({ top: 0, behavior: 'smooth' });
} |
The solution you proposed doesn't make use of I think it makes more sense to have this logic in the afterEach hook. Or at least don't return anything to avoid confusion: scrollBehavior(to) {
let top = 0;
if (to.hash) {
const element = document.querySelector(to.hash);
if (element) {
top = element.offsetTop;
}
}
window.scrollTo({ top, behavior: 'smooth' });
} |
I see it there is freshly added support of smooth scroll in scrollBehavior. Can I ask for an example to make sure I use it properly (right now I'm not even sure if I do)? I use Nuxt 2.13.3 So far I found this to be working (based on @ilyasmez solution): scrollBehavior: function (to) {
if (to.hash) {
setTimeout(() => {
const element = document.querySelector(to.hash);
window.scrollTo({
top: element ? element.offsetTop : 0,
behavior: 'smooth'
})
}, 500)
}
}, Btw, do I even need to make a |
You don't have to use a If you upgrade to scrollBehavior (to) {
return { selector: to.hash, behavior: 'smooth' };
} You don't need to check if @posva are there any plans to update the documentation (API and guide)? |
Thanks! I made it like this now (because there was an error with not finding has in normal pages): return { selector: to.hash || to, behavior: 'smooth' }; Also, it only works when I'm already on the target page. When I change page there is transition going on that takes 0.5s and that's why I need that timeout. Are there any listeners that can be used instead of timeout to wait for transition to finish? Btw, how can I check router version? Because I'm using Nuxt I don't really get to see what's going inside. |
Ah I see, I don't know which transition you're talking about exactly, if it's a custom one then there is no harm in using
If you're using Nuxt you have to wait for a release with the vue-router upgrade (keep an eye on the Nuxt releases page). After the release your solution will look like this: scrollBehavior (to) {
return new Promise((resolve) => {
setTimeout(() => resolve({ selector: to.hash, behavior: 'smooth' }), 500);
});
}, But until then, I recommend sticking to your initial solution, it will work just fine. |
Thanks for such detailed answer! I know it might not be the place, but how actually returning Promise work with router scrollBehavior? I understand Promise will wait for 'something', but what exactly? Initially, I thought it's waiting until all page transitions are done and then it starts to do it's thing. Description in the docs is really short and not saying that much either. |
What problem does this feature solve?
Smooth scrolling to same page anchor tags.
Right now smooth scrolling can only work by custom implementations, but the new Firefox spec contemplates a scrollBehaviour css property which can be polyfilled in older browsers.
Vue-router should take advantage of this new property
What does the proposed API look like?
Basically, the object returned from the scrollBehavior function should have some more parameters and change the current x, y positions into named parameters.
This is an example of the future object to be returned.
{
top: 2500, // this is the x value
left: 0, // this is the y value
behavior: 'smooth' //
};
This is getting implemented in most current browsers, couldn't find the spec thought. If anybody finds it please sahre the link.
Anyway, there is this beatyfull polyfill: https://www.npmjs.com/package/smoothscroll-polyfill
which adds this scrollTo({}) behaviour to old browsers.
I haven't dig much into the vue-router code. But it looks to me as if the only change needed is this file:
https://github.com/vuejs/vue-router/blob/dev/src/util/scroll.js
Maybe we could add some conditions on line 126 to return the current implementation or translate the old object:
{ x, y } to
{ top: x, left: y, behaviour: x }
Sorry if markup sucks, I'll do some more work if this gets atention
The text was updated successfully, but these errors were encountered: