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.

Sujoy Debnath
  • 67
  • 1
  • 4

1 Answers1

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'])
    }
  }
  • Thank you! Worked like a charm! I am trying to optimise it a bit, maybe you have some ideas? https://stackoverflow.com/questions/59074727/how-to-set-the-sensitivity-of-anglar-8-wheel-event – felixo Nov 27 '19 at 16:37
  • 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: https://stackoverflow.com/questions/44764592/angular-4-hostlistener-window-scroll-event-strangely-does-not-work-in-firefox And then applay to it some debounce time by using rxjs operator: https://stackoverflow.com/questions/50739211/how-to-use-debouncetime-in-an-angular-component tell me if you need something more – Lorenzo Imperatrice Nov 28 '19 at 08:02