Multiple scroll components with windowViewport
Hey!
Is there a way, to pause a scroller, especially the scroll subscription when windowViewport is true?
I have multiple pages, which doesnt get destroyed, but are holded in the back (through a custom route strategy).
So i can easily jump between different pages and maintain the scroll positions (without flicker). Thats working great.
I use windowViewport, cause i want the url adress bar to hide on scroll.
So, when i switch pages, the scroll subscriptions doesnt get paused, hence the scroller doesnt even know, whether it should be paused. So there are multiple scroll logs, and if i switch to often, the buffer gets broken (i think, its cause of multiple scrollers on window)
Ideally for me would be a function: datasource.adapter.pause() and datasource.adapter.resume() or similar.
Is this possible?
I wish a great week! :-)
If i could access "Workflow" that would be fine too i think. So i could just deregister/register the onScroll event
@muchbetterug Okay, there are two options I see, that don't require any updates on the lib side.
- You may try to override
window.addEventListenerin your App. Definitely not for production. - Use the scroller core (vscroll) directly with no ngx-ui-scroll wrapper. The example can be taken from here: https://stackblitz.com/edit/vscroll-angular-integration-table-demo?file=src%2Fsc. There you have access to Workflow (and to Routines).
If we want to solve the issue on the scroller's end, we may consider the following options.
-
Expose the Routines class at the consumer (ngx-ui-scroll) level: https://github.com/dhilt/vscroll/tree/v1.5.5#5-routines. Like it was done in the demo from p.2 (so, POC can be done on top of p.2 demo).
RoutineshasonScrollmethod that deals withwindow.addEventListener, so you'd be able to interrupt processing of scroll events. I would avoid exposing Workflow, guessing Routines should be sufficient. -
And the last option is about updating the core, vscroll. As you suggested, there might be implemented pause/resume methods on the Adapter class. I'm not sure what exactly they should do, and here we may discuss... Also, you may try to implement it on top of this integration demo: https://stackblitz.com/edit/angular-ngx-ui-scroll-and-vscroll-integration?file=src%2Fvscroll%2Fclasses%2Fadapter%2Fprops.ts. It is a bit stale (2 years) and needs to be aligned with the latest versions of vscroll/ngx-ui-scroll. But it should be good for POC.
What do you think?
Big thx!
- Possible, but as you stated, not for production
- Definitivly a solution. This would need a lot of rework like it seems
- My preferred solution, without touching the core
- pause should stop listening to the scroll event (especially if windowViewport is active). so there is only one ui-scroll listening to the window onscroll event). resume should restart to listen
I think 3. is ideal, as this wouldnt include touching the core. In the Routines.onScroll i can check, if a specific ui-scroll should process the scroll event. Or override temporaly a specific routine.onScroll to a noop function, if i want the ui-scroll to be inactive
So the main problem is, multiple ui-scrolls thats listen to window onscroll events. I cannot work with *ngIf, cause the ui-scrollers needs to stay initialized.
With the change in 3. i think i can solve this problem.
Thx, really!
@muchbetterug Okay, I started implementing p3 in PR https://github.com/dhilt/ngx-ui-scroll/pull/350. Actually, p4 approach also seems very useful, maybe I'll do both, let's see.
ngx-ui-scroll v3.2.0-beta is available on npm. This release provides Routines experimental API. Details and example can be taken from the demo: https://dhilt.github.io/ngx-ui-scroll/#/experimental#routines.
Speaking of your case with pausing scroll event processing, I would expect you to write something like the following:
onScroll(handler) {
const myHandler = event => {
if (context.stop) { // see demo to get the consumer's context
return;
}
handler(event);
};
// below is a tweaked replica of the original Routines.onScroll implementation, see sources
const eventReceiver = this.settings.window ? window : this.viewport;
eventReceiver.addEventListener('scroll', myHandler);
return () => eventReceiver.removeEventListener('scroll', myHandler);
}
sorry for the late reply, this change works fantastically and is fearly simple, super!
i wish you all the best!!