How to scroll with Router Navigation in Angular 7?
Asked Answered
U

1

5

my sidebar navigation component sidebar.component.html is like this:

<nav class="navbar navbar-expand-lg navbar-dark bg-primary fixed-top" id="sideNav">
  <a class="navbar-brand" href="#page-top">
    <span class="d-block d-lg-none">Sujoy Debnath</span>
    <span class="d-none d-lg-block">
      <img class="img-fluid img-profile rounded-circle mx-auto mb-2" src="assets/img/resume.jpg"             alt="">
    </span>
  </a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-   target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
  <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarSupportedContent">
    <ul class="navbar-nav">
      <li class="nav-item">
        <a class="nav-link" routerLink="/about">About</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" routerLink="/experience">Experience</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" routerLink="/education">Education</a>
      </li>
    </ul>
  </div>
</nav>
and the sidebar.component.ts is like this:

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

@Component({
  selector: 'app-sidebar',
  templateUrl: './sidebar.component.html',
  styleUrls: ['./sidebar.component.css']
})
export class SidebarComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

when I click on About or Experience it Routes to those components as they are mapped in my app-routing-module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { IntroductionComponent } from './introduction/introduction.component';
import { ExperienceComponent } from './experience/experience.component';
import { EducationComponent } from './education/education.component';

const routes: Routes = [
  {path: '', redirectTo: '/about', pathMatch: 'full'},
  {path: 'about', component: IntroductionComponent},
  {path: 'experience', component: ExperienceComponent},
  {path: 'education', component: EducationComponent}

];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

my app.component.html is like this. I am calling the sidebar.component by its selector app-sidebar:

<router-outlet></router-outlet>
<app-sidebar></app-sidebar>

Now how to route the navigation by scrolling such that when I scroll down it automatically moves down from about to experience to education or when I scroll up it automatically moves up from experience to education to about sections.

Unwarrantable answered 1/1, 2019 at 18:54 Comment(4)
you should give more detail about the sidebar.component.html file.Hercule
So what you would like to do is something like this: - You are in "experience" page - Scroll up event detected - Go to "about" page - Is that right?Vagrant
yes @LorenzoImperatrice .. exactly. I want to do that. so i can navigate even without clicking on the router-links.Unwarrantable
thanks. in angular 7 router there are extra options for scrolling .. scrollPositionRestoration: 'enabled', anchorScrolling: 'enabled', but don't know how those helps in scrolling.Unwarrantable
V
8

My example code is on

  1. /page1
  2. /page2
  3. /page3

and is activated when the wheel is used to scroll down and up, it's possible to implement the same thing that I did by adding other events (like with up and down arrow key)

In the app component, I set a window listener for wheel movement, check if the wheel is moving up or down, and last but not least navigate to the wanted route.

  constructor(
    private router: Router
  ) { }

  @HostListener('window:wheel', ['$event'])
  onWheelScroll(evento: WheelEvent) {
    // Scroll down
    if (evento.deltaY > 0) {
      switch (this.router.url) {
        case '/page1': {
          this.router.navigate(['/page2'])
          break
        }
        case '/page2': {
          this.router.navigate(['/page3'])
          break
        }
        case '/page3': {
          break
        }
      }
    } else { // Scroll up
      switch (this.router.url) {
        case '/page1': {
          break
        }
        case '/page2': {
          this.router.navigate(['/page1'])
          break
        }
        case '/page3': {
          this.router.navigate(['/page2'])
          break
        }
      }
    }
  }

This is just one of many solutions.

If you want that the event is emitted only if the wheel is scrolled inside the component you can do like this too:

introduction.component.ts

  HostListener('wheel', ['$event'])
  onWheelScroll(evento: WheelEvent) {
    // Scroll up
    if (evento.deltaY > 0) {
      this.router.navigate(['experience'])
    }
  }

experience.component.ts

  HostListener('wheel', ['$event'])
  onWheelScroll(evento: WheelEvent) {
    // Scroll down
    if (evento.deltaY > 0) {
      this.router.navigate(['education'])
    } else { // Scroll up
      this.router.navigate(['about'])
    }
  }

education.component.ts

  HostListener('wheel', ['$event'])
  onWheelScroll(evento: WheelEvent) {
    // Scroll up
    if (evento.deltaY < 0) {
      this.router.navigate(['experience'])
    }
  }
Vagrant answered 2/1, 2019 at 8:52 Comment(2)
Thank you! Worked like a charm! I am trying to optimise it a bit, maybe you have some ideas? #59075227Catinacation
Happy to hear it! Anyway yes, you can try to add a some debounce time, in that way user can scroll lot of time and change page just one. The first thing is to transform the HostListener in an Observable like this answer: #44765092 And then applay to it some debounce time by using rxjs operator: #50739711 tell me if you need something moreVagrant

© 2022 - 2024 — McMap. All rights reserved.