1

How can I make sure that when there's a click on a router link within the <app-navbar> component, the browser will scroll down to the router outlet ?

This is what my app.component.html looks like at the moment:

<div class="container-fluid h-100">
  <app-navbar></app-navbar>
  <div class="row h-100">
    <app-header class="h-100 overflow-auto col-md-12  col-lg-5"></app-header>
    <div id="main" class="h-100 overflow-auto col-md-12 col-lg-7">
      <router-outlet #o="outlet"></router-outlet>
    </div>
  </div>
</div>

the <app-navbar>contains router-links and the <app-header>takes up 100% of the height on mobile. So I want to make sure that whenever a user clicks on a link in the navbar, the page scrolls down to the newly loaded component under the <app-header>

I had a look at this library : https://www.npmjs.com/package/ngx-page-scroll but couldn't manage to make it scroll (I suppose because I was trying to scroll to an element of a different component).

Just when I was about to edit this message I found this library : https://www.npmjs.com/package/angular-scroll but same thing, I am not sure how to make it work.

3
  • Start with scrollIntoView Commented Oct 16, 2019 at 21:03
  • @ChrisW. not a great suggestion since the browser support isnt very good.. developer.mozilla.org/en-US/docs/Web/API/Element/… Commented Oct 16, 2019 at 23:07
  • @SmokeyDawson All browsers support it, you just don't get the nifty options like smooth scroll in a couple of them.... Commented Oct 17, 2019 at 14:03

1 Answer 1

4

After a bit of research, here is a solution that works :

  1. Make sure the <app-module>gets the click event in the <app-navbar>

Exemple of a link in app-navbar.html :

<a class="nav-link" routerLink="bio" routerLinkActive="active" (click)="scrollToMain()" >Bio</a> 

Exemple of app-navbar.ts

import { Component, EventEmitter, Output } from '@angular/core';

@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.css']
})
export class NavbarComponent {
  @Output() scroll: EventEmitter<any> = new EventEmitter();

scrollToMain() {
    this.scroll.emit(true);
  }
}
  1. Catching the event in app.component.html
<div class="container-fluid h-100">
  <app-navbar  (scroll)="onScroll('#main')"></app-navbar>
  <div class="row h-100">
    <app-header class="h-100 overflow-auto col-md-12  col-lg-5"></app-header>
    <div id="main" [@routeAnimations]="o && o.activatedRouteData && o.activatedRouteData['animation']"
      class="h-100 overflow-auto col-md-12 col-lg-7">
      <router-outlet #o="outlet"></router-outlet>
    </div>
  </div>
</div>

Acting on the event in app.component.ts

import { Component, Inject} from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { PageScrollService } from 'ngx-page-scroll-core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  constructor(private pageScrollService: PageScrollService, @Inject(DOCUMENT) private document: any) {
  }

  onScroll(target) {
    this.pageScrollService.scroll({
      document: this.document,
      scrollTarget: target,
    })
  }
}

It could work as well with scrollIntoView but I used the ngx-page-scroll to make things smother : https://www.npmjs.com/package/ngx-page-scroll.

Hope it helps someone :)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.