Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 10 get router active fragment when scrolling past the fragment?

I'm trying to highlight in the navigation which active fragment you're scrolling past.

Adding the fragment & navigation to the fragment is simple and works well, example:

      class="nav-button unselectable"
      matRipple
      routerLink="/"
      fragment="features"
      [ngClass]="{ 'nav-active': (active_fragment | async) === 'features' }"

But the router obviously can't know which element you're scrolling about so I'm trying to listen on the scroll event and check the nearest element using the Y position.

But my landing page isn't a child of my navigation so the viewchild doesn't work, example:

navigation component:

  @ViewChild('features', { static: false })
  private _features: ElementRef;

  @HostListener('window:scroll', ['$event'])
  private _update_active_fragment(event: any) {
    event.preventDefault();

    console.log(window.pageYOffset);
    console.log(this._features.nativeElement);
  }

Landing page component:

  <app-features #features id="features"></app-features>

But features native element is undefined.

My question is:

  • How else can I achieve this feature?
  • How can I get the element ref of from the navigation component?
  • How can I get the y position of the features element in the navigation component?
like image 995
SebastianG Avatar asked Nov 16 '22 07:11

SebastianG


1 Answers

Made a new navigation service:

public active_fragment: BehaviorSubject<string> = new BehaviorSubject('');

  constructor(private readonly route: ActivatedRoute) {
    this.route.fragment.subscribe((frag) => {
      this.active_fragment.next(frag);
    });
  }

In my navigation component:

      [ngClass]="{
        'nav-active': (navigationService.active_fragment | async) === 'home'
      }"

in my landing component that contains my fragments:

  @ViewChild('features', { read: ElementRef })
  private _features: ElementRef;
  @ViewChild('benefits', { read: ElementRef })
  private _benefits: ElementRef;


  @HostListener('window:scroll', ['$event'])
  private _update_active_fragment(event: any) {
    event.preventDefault();
    switch (true) {
      case window.pageYOffset >=
        this._some_previous_element.nativeElement.offsetTop &&
        window.pageYOffset <= this._features.nativeElement.offsetTop: {
        this.navigationService.active_fragment.next('network-rail-feedback');
        break;
      }

      case window.pageYOffset >= this._features.nativeElement.offsetTop &&
        window.pageYOffset <= this._benefits.nativeElement.offsetTop: {
        this.navigationService.active_fragment.next('features');
        break;
      }


      default:
        break;
    }
  }

like image 181
SebastianG Avatar answered Dec 15 '22 09:12

SebastianG