How to make component disappear when scroll down in Angular?

Viewed 4518

I am looking for a simple way to make a different header appear when the normal one is scrolled down. I have been looking for many solution but they're all involving long code..

So here is the solution I found but that isn't working since y doesn't implement itself..

Here is the TypeScript

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

...

export class HeaderComponent implements OnInit{

    y = window.scrollY;

    myID = document.getElementById("header");

    myID2 = document.getElementById("header2");

ngOnInit() {
        this.myScrollFunc();
        window.addEventListener("scroll", this.myScrollFunc);
      }

      myScrollFunc() {
        if (this.y >= 150) {
          this.myID2.className = "bottomMenu hide"
          this.myID.className = "bottomMenu show"
        } else {
          this.myID2.className = "bottomMenu show"
          this.myID.className = "bottomMenu hide"
        }
      };

    }

The HTML

<div id="header" class="bottomMenu show"> ... </div>

<div id="header2" class="bottomMenu hide"> ... </div>

And the .css

.hide {
  opacity: 0;
  left: -100%;
}
.show {
  opacity: 1;
  left: 0;
}

This apparently is supposed to work and looks simple but it doesn't work for me..

EDIT : If you have a simpler way I am also open, the solution isn't mainly to correct this one.

EDIT 2 : Still no answer, if anyone have an idea, or if there is a simpler solution, like if (position !=0) { y = 1 } else { y = 0 } and i'd add y in some ngIf in the HTML... ?

EDIT 3 : I finally found a solution, here is my code if someone has the same problem :

HTML

<div id="header" *ngIf="scrolled == 0"> ... </div>
<div id="header2" *ngIf="scrolled == 1"> ... </div>

TypeScript

export class HeaderComponent implements OnInit{

  scrolled = 0;

  @HostListener('window:scroll', ['$event'])
  onWindowScroll($event) {
    const numb = window.scrollY;
    if (numb >= 50){
      this.scrolled = 1;
    }
    else {
      this.scrolled = 0;
    }
  }
}

Easier than long listener

Thank you very much for your help in advance !

4 Answers

HTML

<div id="header" *ngIf="scrolled == 0"> ... </div>
<div id="header2" *ngIf="scrolled == 1"> ... </div>

TypeScript

export class HeaderComponent implements OnInit{

  scrolled = 0;

  @HostListener('window:scroll', ['$event'])
  onWindowScroll($event) {
    const numb = window.scrollY;
    if (numb >= 50){
      this.scrolled = 1;
    }
    else {
      this.scrolled = 0;
    }
  }
}

Easier than long listener

I am updated your code try this.

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

...

export class HeaderComponent implements OnInit{

    y = window.scrollY;
    myID = document.getElementById("header");
    myID2 = document.getElementById("header2");

ngOnInit() {}

@HostListener('window:scroll', ['$event'])
onWindowScroll($event) {
          if (this.y >= 150) {
          this.myID2.className = "bottomMenu hide"
          this.myID.className = "bottomMenu show"
        } else {
          this.myID2.className = "bottomMenu show"
          this.myID.className = "bottomMenu hide"
        }
}

}

If you are using angular and want to hide certain elements you should just use *ngIF which will render or not the element and there's no need to apply css to hide it, and since you are only showing 1 element or the other you can just bind both to the same variable but with inverse condition.

<div id="header" *ngIf="!scrolled" class="bottomMenu"> ... </div>

<div id="header2" *ngIf="scrolled" class="bottomMenu"> ... </div>

And in your component all left to do is turn scrolled to on if it get past your desired height.

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

...

export class HeaderComponent implements OnInit{

    scrolled = false;

    @HostListener('window:scroll', ['$event'])
    onWindowScroll($event) {
        this.scrolled = $event.srcElement.scrollTop >= 150;
    }
}

Edit: I added the HostListener from upinder kumar answer since that's the proper way to register to events in angular.

Edit 2 : I in the past have implemented something similar to this but didn't used a hardcoded px (in your case you using 150 px ) size to scroll event but yet instead I calculated that my header would change after 10% of the scroll has been moved with the following expression :

this.scrolled = $event.srcElement.scrollTop / $event.srcElement.scrollHeight > 0.1 ;

Unfortunately, using @HostListener('window:scroll') did not work for me. For moderns browsers, you can use the wheel event (WheelEvent) instead.

I get the scroll for the entire app and share among the components, so that I can do whatever I want with the event.

share.service.ts

  public isScrolledUp = new BehaviorSubject<boolean>(null);

  public addScroll(isScroll: boolean) {
    this.isScrolledUp.next(isScroll);
  }

app.component.ts

  constructor(private sharedS: SharedService){}

  public onScroll(event: WheelEvent) {
    // Move Up (negative)
    // Move Down (positive)
    this.sharedS.addScroll(event.deltaY > 0);
  }

app.component.html

<div (wheel)="onScroll($event)">
    <!--Here goes your components-->
    <router-outlet></router-outlet>
</div>

Then, any component you like just import the SharedService and subscribe the property isScrolledUp.

any.component.ts

  private sub: Subscription;
  public isScrollUp: boolean; // you can do whatever you want. Ex: hide some buttons
  constructor(private sharedS: SharedService){}

  ngOnInit(): void {
    this.sub = this.sharedS.isScrolledUp.subscribe((res) => this.isScrollUp = res);
  }

any.component.html

<footer *ngIf="!isScrollUp"></footer>
<button *ngIf="isScrollUp"></button>
Related