Skip to content
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

[history] Restoring scroll position when the back button is pressed #322

Open
norbertkeri opened this issue Mar 22, 2023 · 1 comment
Open

Comments

@norbertkeri
Copy link

norbertkeri commented Mar 22, 2023

Hey,

I started dabbling with the yew framework, and I got to the point where I would like to implement scroll restoration. I realize this is not the yew issue tracker, but I think it's very related to gloo-history.

The problem in a nutshell:

  • You have a component where you do fetch-after-render, by requesting data from some endpoint.
  • The data arrives, and there is so much data that (vertical) scrollbars appear
  • You scroll down, and click on a link, and you arrive at some other subpage
  • You press the back button in the browser, to get back to the prevous page
  • You will be at the top of the page, regardless of how much you scrolled down

The reason you are at the top is because when the browser renders the page from the bfcache, and tries resetting the y scroll position, the data for the page is not yet there, there is nothing to scroll down to. The XHR request is still in-flight at this point and it will arrive eventually, but the browser already made an attempt to reset the scroll position.

I could implement scroll restoration in userland:

  • When the user clicks a link, store the page's scrollTop
  • When the XHR request finishes, check if the back button was pressed
  • If yes, set window.scrollTop to the saved value, if any

The missing piece is the check for the back button. I went into the yew source code to see if there is any indication whether the back button was pressed, but there isn't any. I tried grepping for popstate, since it must definitely be listening on that, otherwise the back button would not work at all with yew apps, but found nothing. Digging further, I found out the reason I'm not finding anything in the yew_router crate, is because all history handling is actually handled by gloo_history!

I found the relevant line at:

https://github.com/rustwasm/gloo/blob/master/crates/history/src/browser.rs#L283

If the notify_callbacks could pass an extra parameter that signals that it was a popstate event, I could implement scroll restoration. React router supports this by exposing a "history action": https://reactrouter.com/en/main/start/concepts#definitions

Can anyone give me some tips on how to implement this, and confirm this is actually a good way to do this? I don't have that much rust knowledge, but I could maybe give it a try.

@futursolo
Copy link
Collaborator

If the notify_callbacks could pass an extra parameter that signals that it was a popstate event

I think you can try to store a state with the history entry?
If it doesn't have an entry with the previous scroll position, then it should be a new entry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants