Home > database >  Angular Scroll to Next Route when page hits bottom
Angular Scroll to Next Route when page hits bottom

Time:09-28

While scrolling down from the first route, when the page hits the end then automatically it should route to next route. As I have Lazy loaded module, I need them to appear as single page scroll through all routes.

CodePudding user response:

You have two ways to know when an element is visible in screen:

1.- Listening scroll event

import {fromEvent} from 'rxjs'

@ViewChild("elementBottom") element:ElementRef

$obs=fromEvent(window,'scroll').pipe(
   filter(()=>{
     const position = this.element.nativeElement.getBoundingClientRect();

    // checking whether fully visible
    return (position.top >= 0 && position.bottom <= window.innerHeight)
   }),
   take(1)
)

2.- Using Intersection Observer

For this you create a directive "stolen" from Sascha Wolff article like

@Directive({
  selector: '[appIntersection]',
})
export class IntersectionDirective implements OnInit, OnDestroy {
  observer: IntersectionObserver;
  previousEntry: IntersectionObserverEntry;
  subscription:Subscription=null;
  @Input() rootMargin = '0px 0px 0px 0px';
  @Output() scrollEnd: EventEmitter<any> = new EventEmitter();
  constructor(private el: ElementRef,private router:Router) {}
  ngOnInit() {
    this.subscription=this.router.events.pipe(
   filter((ev)=>ev instanceof NavigationEnd)
    ).subscribe(()=>{
      this.previousEntry=null
    })
    this.observer = new IntersectionObserver(
      (entries) => {
        const entry=entries.find(x=>x.isIntersecting)
          if (!this.previousEntry?.isIntersecting && entry) {
            this.scrollEnd.emit();
            this.previousEntry = entry;
          }
      },
      {
        rootMargin: this.rootMargin,
        threshold:1
      }
    );

    this.observer.observe(this.el.nativeElement);
  }
  ngOnDestroy(): void {
    this.observer.disconnect();
    this.subscription && this.subscription.unsubscribe();
  }
}

Now your main.component can be like

<router-outlet></router-outlet>
<div appIntersection (scrollEnd)="scrollEnd()" style="height:3rem"></div>

export class AppComponent  {
  constructor(private router:Router){}
  scrollEnd()
  {
    switch(this.router.url)
    {
      case "/":
        this.router.navigate(['/company']);
        break;
      case "/company":
        this.router.navigate(['/products']);
        break;
      case "/products":
        this.router.navigate(['/']);
        break;
    }
  }
}

A stackblitz

NOTE: See that I enclosed all teh component in a div with the class whole

.whole{
  min-height: 100vh;
}

To be sure that we need make a scroll

  • Related