KingSora / OverlayScrollbars

A javascript scrollbar plugin that hides the native scrollbars, provides custom styleable overlay scrollbars, and preserves the native functionality and feel.
https://kingsora.github.io/OverlayScrollbars
MIT License
3.9k stars 215 forks source link

Is there a way to consistently do auto scroll on page load? #680

Open ryanzec opened 1 month ago

ryanzec commented 1 month ago

Is your feature request related to a problem? Please describe. I have a page that I need to auto scroll when the page loads however if the scrollable element is also being initialized on that page load, I have issues with getting the auto scroll to work consistently.

At first it was not scrolling at all and it seemed like it was because the overlay scrollbars was not initialized so the scrollHeight at the time I was calling scrollTo() on the element was not right so I added code to do:

// using scrollElement.parentElement since the scrollElement in the content element and not the initialize element
instance = OverlayScrollbars(scrollElement.parentElement)

and it waits until instance is populated (or a timeout triggers to avoid infinite loop). This does properly wait until instance is populated and the value of scrollHeight is now correct when I call scrollTo(), The scrolling now works most of the time but there are still random points where it fails. I tried to add to the initialize / 'updateevents add those seem to never be called. I tried usingrequestAnimationFrame()` but that did not work. The only things that seems to work consistently (though I am sure there will be time where it won't, just low chance) is by adding this:

instance = OverlayScrollbars(scrollElement.parentElement)

await new Promise((resolve) => setTimeout(resolve, 250));

Now I am pretty sure this is not a great way to fix this issue however I just can't seem to find any way to know when overlay scrollbars are completely ready for me to call scrollTo() on the viewport without it failing.

This seems to only be an issue if the overlay scrollbar is initializing on the load of the page. This example is using a SPA and if I am on a different page that have the overlay scrollbar element already initialized and I move to the page with the auto scroll functionality (the overlay element does not change, just the elements in it), the auto scroll seems to work every time.

Describe the solution you'd like I am creating this as a feature as I am not sure if it is a bug but I am looking for a way to be able to when the viewport is ready to call scrollTo() on it and have it work properly.

Describe alternatives you've considered I am opened to other ideas I have not thought of.

KingSora commented 1 month ago

@ryanzec Good day :)

If I'm understanding you correctly, you want to scroll to a certain scroll position after OverlayScrollbars is initialized.. This should be pretty straight forward, I can create a small example for you. But before that please answer those questions first:

  1. Is the content of the scroll element static or changed via javascript in any way?
  2. Can I assume that as soon as the OverlayScrollbars viewport has any overflow I'm ready to scroll?
ryanzec commented 1 month ago
  1. Is the content of the scroll element static or changed via javascript in any way?
  2. Can I assume that as soon as the OverlayScrollbars viewport has any overflow I'm ready to scroll?

@KingSora Thanks for the reply, to answer your questions:

  1. The data is dynamic, I am using svelte but the content initially is empty and then loaded on the client side.
  2. That would be correct.
KingSora commented 1 month ago

@ryanzec Here is a simple example: https://stackblitz.com/edit/vitejs-vite-utea9y?file=main.js

Its not in svelte but uses vanilla javascript.. the concept should be the same though. If the example is not matching the conditions of your app please feel free to adapt it and send your version which I could then adapt.

KingSora commented 1 month ago

@ryanzec any feedback from your side? :)

ryanzec commented 1 month ago

@KingSora Sorry for the delay. The issue with the approach in the example is that it assumes access to the creation of the overlayscrollbars and where content that is being generated to cause the scroll to happen are in the same place. The structure was something like like:

<PageWrapper>
  <StaticNavigation />
  <ScrollArea>
    <PageContent />
  </ScrollArea>
</PageWrapper>

Now the overlay scrollbar was being applied in the ScrollArea component however the contents of PageContent is dynamic. Further to the issue compared to the example, the auto scroll should only happen for a specific page so even though both Page1 and Page2 might be scrollable, we only want when Page2 is loaded to auto scroll and not Page1 even if the content for Page1 does have a scroll.