ItalyPaleAle / svelte-spa-router

Router for SPAs using Svelte 3
MIT License
1.53k stars 105 forks source link

restoreScrollState true sends me to the very top of the page #282

Open jonathanstegall opened 1 year ago

jonathanstegall commented 1 year ago

In my App.svelte, I have <Router {routes}/>, and when I navigate (with push or with use:link), the application preserves a scroll position that may not exist. For example, if I'm on a very long page and I click a link that goes to a very short page, the browser position will be way below the content.

When I try using <Router {routes} restoreScrollState={true}, regardless of whether I click back or click push or use:link, the application sends me to the very top of the browser window. Because in this case it's far above <Router> (header elements, navigation elements, etc.) the browser window is far away from the content it was viewing.

Are there any settings I can use for restoreScrollState, or ways to extend what it's doing? Ideally, I'd love it if the application could remember the previous scroll position, if applicable, and otherwise if it could just scroll to where <Router> starts.

jonathanstegall commented 1 year ago

I figured out that on the component where the data is ultimately rendered (it didn't work on App.svelte), I can add this:

import { onMount } from 'svelte';
onMount(async () => {
    const el = document.querySelector('.my-selector');
    if (!el) return;
    el.scrollIntoView({
        behavior: 'smooth'
    });
});
ItalyPaleAle commented 1 year ago

The above would work although directly accessing the DOM is considered anti-pattern in Svelte.

In your case, it's hard to be able to answer without seeing some code. It could be due to the fact that the content may be dynamically generated and loaded inside an onMount?

PS: onMount is not necessary if you're not doing SSR (and if you're using this router, I can probably guess you aren't!)

phocks commented 5 months ago

I'm having the same. No matter what it simply sends me to the top of the page. I'll see if I can find the mechanism that remembers the scroll position in the code. I'm using wrap async components, so maybe that has something to do with it?

phocks commented 5 months ago

Oh OK. I just found this. Looks like I mistook the expected behaviour of restoreScrollState.

/**
 * If set to true, the router will restore scroll positions on back navigation
 * and scroll to top on forward navigation.
 */
export let restoreScrollState = false

I was expecting the scroll state to be remembered on page reload and if I forward navigated to a page, to remember where I last was at, the last time I was on that page.

I'll continue to add my own mechanism for remembering scroll position, using localStorage or something. Thanks.