Troubleshooting: @HostListener for window scroll event not functioning as expected

Having trouble creating a sticky header that stays fixed when scrolling down in an Angular 4 application. The scroll event is not being detected.

The header is located in the layout component, while the content I want to be scrollable is placed in the routes component. Could this arrangement be causing the issue?

Here is the implemented code:

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">

Answer №1

I encountered a similar issue recently, but I found a solution by ensuring that the component element is the one actually scrolling and that it has an overflow property set to either scroll or auto.

If not, you can try the following code snippet:

@HostListener('scroll')
  public handleScroll(): void {
  console.log('scrolling');
}

Answer №2

It seems like the issue lies within your layout setup. The scroll event will only work if the component template element is able to scroll.

Make sure to set the overflow property of the div to scroll and adjust the dimensions of the div so that scrolling can be triggered.

To address this issue, I recommend creating a directive and applying it to a div with 100vh in height and 100vw in width for optimal functionality.

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');
    }
}
 

Check out this stackblitz example that I put together.

Answer №3

Here are some ways to capture scroll events:

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

or

<div (scroll)="onScroll($event)"

Answer №4

Dealing with a similar problem, I made the following addition to "nav.component":

@HostListener('window:scroll', [])
onWindowScroll() {
    console.log(window.scrollY);

    if (window.scrollY > 90) {
        this.isSticky = true;
    } else {
        this.isSticky = false;
    }
}

Answer №5

Was unable to get it functioning using the scroll event, but found success with the wheel event:

@HostListener('window:wheel', ['$event'])
onWheel(event: MouseEvent) {
  // customize your actions here
}

Answer №6

The problem I encountered was due to a straightforward overflow-x: hidden style set on the <html> element. By moving this style to the <body> element, I was able to resolve the issue without altering my overflow settings.

Scroll events can be detected by any component, independent of their hierarchical relationship. Parent/child relations do not have an impact on this functionality.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular: efficient exchange of information among components

I have a component X that handles a WebSocket. And within component X, I also have multiple presentation components (e.g. Y). Whenever the WebSocket receives a specific message, I need to perform an action in a particular component (e.g. refresh data). To ...

Compilation of Zod record with predefined keys

I need to create a dictionary similar to a zod schema for an object with multiple keys that are already defined elsewhere, all sharing the same value type. Additionally, all keys must be required. const KeysSchema = z.enum(['a', 'b', &a ...

after ajax post, enhance original object by merging with the latest server values

After making a call to the server and successfully saving some data, I need to update the JSON array object that I have with new values. Here is a snippet of my code: [ { "id": 1, "uuid": "ce54acea-db20-4716-bceb-2f3deb1b2b86", "name": null, ...

If an interface property is set as (), what significance does it hold?

While exploring the Vue.js source code located at packages/reactivity/src/effects.ts, I came across this snippet: export interface ReactiveEffectRunner<T = any> { (): T effect: ReactiveEffect } I'm curious, what does () signify in the code ...

Developing a Customized Filtering Mechanism in Angular 8

I have some experience working in web development, but I am relatively new to Angular. My current project involves creating a simple filter for a table's column based on user input. However, I'm facing an issue where typing in a single letter fil ...

Strange compilation error encountered with ng-packagr due to Angular @Input inheritance

Encountering a perplexing error message in Angular 7 while working with @Input inheritance. The error message seems illogical because I have 1 mandatory @Input and 2 optional @Input, so things should align... Error: Directive MyComponent, Expected 2 argum ...

Is it necessary to create a wrapper for Angular Material2 components?

I have multiple angular 5 projects in progress and my team is considering incorporating material design components from https://material.angular.io/. Would it be beneficial to create a wrapper layer to contain the material design components? This would me ...

Child component responsible for closing the modalI will guide you through

A component in my project has a header with a modal window that pops up when clicked: <a (click)="open(content)" class="in">Sign in</a> <ng-template #content let-modal> <button type="button" class="close" aria-label="Close" (click)= ...

The issue lies in attempting to assign an 'Observable<number[]>' to a parameter expecting an 'Observable<ProjectObject[]>'. This obstacle must be overcome in order to successfully create a mock service

I am currently working on setting up a mock service for unit testing, but I am facing an issue where the observable is not returning the expected fake value. Can someone please assist me in resolving this problem and also explain what might be wrong with m ...

"An error has occurred stating that the header is not defined in

It is a coding issue related to payment methods. The headers type is undefined in this scenario, and as a newcomer to typescript, pinpointing the exact error has been challenging. An error message is indicating an issue with the headers in the if conditio ...

No issues raised by Typescript/tslint regarding this in arrow function

After making some creative adjustments, this is what I came up with: const TopBar = () => ( <Button onPress={this.onPress} // No errors shown /> ) Although all my other rules in tslint.json are functioning properly. Is there a way to ma ...

In Angular 5, a variable's value becomes undefined once it is subscribed to outside of its assigned

I keep encountering an undefined value when trying to assign the subscribed value to a variable in my code snippet below. service.ts getIpAddress() : Observable<any> { return this.http .get(this.Geo_Api) .map((response: ...

Invoke a function within a component, within that very component

Hey there, I've got an Angular 2 component with a @HostListener. My goal is to call a method from this component using the @HostListener. Check out the code snippet below for my attempt at implementing this: The Component import { Component, Host ...

Unused Angular conditional provider found in final production bundle

Looking for a way to dynamically replace a service with a mock service based on an environment variable? I've been using the ?-operator in the provider section of my module like this: @NgModule({ imports: [ ... ], providers: [ ... en ...

The compilation of angular-cli version 25.5 encountered an error during module build

Issue Upon upgrading angular-cli from 22.1 to 25.5 (installing angular-cli@latest) and angular from version 2.2.3 to 2.3.1, the following problem occurred: ERROR in ./src/app/app.module.ts Module build failed: TypeError: Cannot read property 'text&a ...

Having trouble deploying an Angular Universal app to an AWS S3 bucket with server-side rendering (SSR

Transitioning from an Angular9 application to make it SEO friendly required me to switch to Angular Universal SSR. I followed the steps below: Ran the command: ng add @nguniversal/express-engine Ran the command: npm run dev:ssr Ran the command: npm run bu ...

Discovering if "back" and "forward" navigation are accessible using Angular's Location service

As I work on my Progressive Web App, I am incorporating back and forward navigation buttons specifically for standalone mode. To make this happen, I have integrated the Location service in my component and added the following code: public onForward() { ...

Why do I keep being told that the property doesn't exist?

I have the following code in one file: function test<T extends {}>(arg:T):any { return arg.name } In another file, I have this code: interface IItem { name: string } console.log(test<IItem>({name:'3'})) When I try to access ...

Explaining the process of defining an object type in TypeScript and the conversion from JavaScript

Currently, I am attempting to enhance the background of a React website developed in typescript (.tsx) by incorporating particles. My approach involves utilizing the particle-bg component available at: https://github.com/lindelof/particles-bg However, whe ...

Notify other components in Angular when a change has occurred without relying on intervals

In the footer component of my project, I currently have a code snippet that runs a check on LocalStorage every 15 seconds using a timer. ngOnInit() { const checkLocalStorage = interval(15000); checkLocalStorage.subscribe(data => { ...