IdoLeshkowitz
Restoring sticky live view scroll position during live redirects
Hey everyone ![]()
Im using sticky live view to render a navbar across my app. The issue is the navbar scroll position resets whenever a live redirect happens within the app. How would you recommend approaching this?
First Post!
codeanpeace
Welcome!
Hmm, that’s odd – LiveView’s definitely gotten better at restoring scroll position out of the box in more recent versions, but it sounds like sticky/nested LiveViews might still be a problem.
Anyways, I’d probably stash scroll position on the client and restore it via a phx-hook on mounted rather than tracking it from the server since it’s a UI concern.
# pseudocode
Hooks.StickyNav = {
mounted(){
// stash scroll top
this.el.addEventListener("scroll", e => {
// consider debouncing
sessionStorage.setItem("stickyNavScrollTop", this.el.scrollTop)
})
// restore scroll top
scrollTop = sessionStorage.getItem("stickyNavScrollTop")
if (scrollTop) { this.el.scrollTop = scrollTop }
}
}
note: session storage is tied to an individual tab so local storage may be the way to go if you want to handle new tabs as well
And just a heads up, live_redirect has been deprecated for a good while now so it may be worth updating soon – especially with 1.0 around the corner!
Last Post!
bu6n
Seems like this is working for my use-case:
function debounce(func, timeout = 100) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
}, timeout);
};
}
/**
* A hook used to keep the scroll position of elements
* inside a sticky liveview after a live navigation.
*/
/**
* Session storage key for restoring panel size.
*/
const SCROLL_POSITION_STORAGE_KEY = "scroll-position";
const KeepScrollPosition = {
restoreScrollPosition(_info) {
scrollTop = sessionStorage.getItem(`${this.el.id}-${SCROLL_POSITION_STORAGE_KEY}`);
if (scrollTop) {
this.el.scrollTop = scrollTop;
}
},
mounted() {
const save = debounce(() => {
sessionStorage.setItem(`${this.el.id}-${SCROLL_POSITION_STORAGE_KEY}`, this.el.scrollTop);
});
this._restoreScrollPosition = this.restoreScrollPosition.bind(this);
this.el.addEventListener("scroll", save);
window.addEventListener("phx:page-loading-stop", this._restoreScrollPosition);
},
destroyed() {
window.removeEventListener("phx:page-loading-stop", this._restoreScrollPosition);
},
};
export { KeepScrollPosition };
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









