Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Window scroll event using @HostListener not working

I have problem making sticky header when scrolling down, in an Angular 4 application. Scroll event can't be detected.

Header is placed in the layout component, and the content I want to be scrolling is placed in routes component. May that be the problem?

This is the code I implemented.

In layout.component.ts

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

import { DOCUMENT } from "@angular/platform-browser";

@Component({

  selector: 'app-layout',

  templateUrl: './layout.component.html',

  styleUrls: ['./layout.component.css']
})

export class LayoutComponent implements OnInit {

  public navIsFixed: boolean = false;

  constructor(public router: Router, @Inject(DOCUMENT) private document: any) { }

  @HostListener('window:scroll', [ ])

    onWindowScroll(){
      const number = window.pageYOffset || 
      document.documentElement.scrollTop || 
      document.body.scrollTop || 0;
      if (number > 50) {
        this.navIsFixed = true;
      } else if (this.navIsFixed && number < 10) {
      this.navIsFixed = false;
      }
    }
}

In layout.component.html

<div [class.fixed]="navIsFixed" class="header">
like image 336
tolceza Avatar asked Aug 29 '17 11:08

tolceza


3 Answers

I just had the same problem, all what I had to do was to make sure that the component element is actually what is scrolling & that it has a overflow property with values scroll or auto.

Otherwise just this worked:

@HostListener('scroll')
  public asd(): void {
  console.log('scrolling');
}
like image 191
Zahema Avatar answered Nov 20 '22 00:11

Zahema


Your layout must be the source of the issue. The scroll event works only when the the component template element can actually scroll.

Make sure the div has overflow property set to scroll. Also, change the div dimensions so the scroll could trigger.

In order to make it work, I would suggest to make it to the directive and set to a div that has 100vh in height and 100vw in width.

import { Directive, ElementRef, HostListener } from '@angular/core';

@Directive({ selector: '[trackScroll]' })
export class TrackScrollDirective {
    constructor(private el: ElementRef) {
    }

    @HostListener('document:scroll', [])
    onScroll(): void {
         console.log('I am scrolled');
    }
}
 

See this stackblitz that I made.

like image 38
Vega Avatar answered Nov 20 '22 00:11

Vega


This should give you scroll events:

@HostListener('scroll', ['$event'])
onScroll(event) {
  ...
}

or

<div (scroll)="onScroll($event)"
like image 25
Carsten Avatar answered Nov 20 '22 01:11

Carsten