Updating the navigation item list according to the content being shown: A step-by-step guide

I currently have a navigation menu set up with the following code:

<ul class="menu-left pl-3">
    <li *ngFor="let period of periods; let i = index">>
        <a class="mb-4 fragment-link" [class.active]="selectedIndex === i"
           [ngClass]="{'text-dark font-weight-bold': selectedIndex === i}" (click)="setIndex(i)"
           [routerLink]="['/registrations/list']" fragment="d{{period}}">
            {{period}}
        </a>
    </li>
</ul>

The 'period' in this case represents a school year, for example, 2017-2018. I am looking to implement dynamic scroll functionality on the page. The goal is to highlight the navigation item corresponding to the school year of the card currently visible to the user. Typically, users register for 2 semesters per school year, making it essential for the navigation to reflect the displayed card. Unfortunately, binding the nav entry directly to a registration entry is not a viable solution.

The structure of the cards is as follows:

<div class="reg_courses_body__main">
          <div *ngFor="let registration of registrations">
            <div id="d{{registration?.registrationYear.alternateName}}">
            <div class="card mt-2 year">
              <div class="card-body">
....
              </div>
           </div>
        </div>
</div>

I have attempted the following approach:

    $(window).scroll(function() {
      const scrollDistance = $(window).scrollTop();
      const elements = document.getElementsByClassName('year');
      const periods = document.getElementsByClassName('fragment-link');
      let j = 0;
      for ( let i = 1; i < elements.length; ++i) {
        j = i;
        if ($(elements.item(i)).position().top - 70 <= scrollDistance) {
          continue;
        } else {
          for ( let k = 0; k < periods.length; ++k ){
            if( elements.item(i).parentElement.id === 'd'.concat(periods.item(k).textContent.replace(/\s+/g, ''))) {
              j = k;
            }
          }
          $('.menu-left li a.active').removeClass('active text-dark font-weight-bold').addClass('text-gray-600');
          $('.menu-left li a').eq(j).addClass('active text-dark font-weight-bold');
        }
      }
  }).scroll();

However, the results were not entirely as expected. 🤔

Answer â„–1

I implemented the use of @HostListener in the following way:

@HostListener('window:scroll', ['$event'])
  public onWindowScroll(event: ScrollEvent): void{
    if ( !this.isScrolling ) {
      this.isScrolling = true;
    }
    const currentScroll = $(window).scrollTop();
    const elements = document.getElementsByClassName('year');

    for (let i = 1; i < elements.length; i++) {
      const currentElement = elements.item(i);

      if ($(elements.item(i)).position().top <= currentScroll) {
        this.selectedIndex = this.periods.indexOf(currentElement.parentElement.id.slice(1, currentElement.parentElement.id.length));
        $('.menu-left a.active').removeClass('active text-dark font-weight-bold');
        $('.menu-left a').eq(this.selectedIndex).addClass('active text-dark font-weight-bold');
      }
    }
  }

This code snippet fetches elements with the class .year, examines their position on the page, and updates the navigation menu. If an element's position is less than or equal to the current scroll position, it adjusts the styling of the navigation menu by toggling classes accordingly. The selectedIndex variable stores the index derived from the parent ID of the current element, adjusted by removing the first character due to the format of the IDs being like d{{period}}.

A special thanks to @khushi for guiding me in the right direction.

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

Is it possible to filter JavaScript Array while ensuring that select options do not contain duplicate IDs?

I am utilizing two datatables with drag and drop functionality. Each row in the datatables contains IDs. When I drag a row from table 1 to table 2, the data is stored in an Array. I have an addArray function that pushes the IDs into the Array, filters out ...

The Grails remoteFunction is able to update the view by dynamically using templates that incorporate Jquery, effectively identifying and interacting

Having an issue with my view containing a button that triggers a remoteFunction (ajax call) to update a div with a template including a jQuery function. However, the jQuery function is not recognizing elements in the updated div, causing rendering issues. ...

Inverting the hierarchy of a tree structure

I am currently working with a tree structure and utilizing the jstree jQuery plugin. My main objective is to reverse the structure. https://i.sstatic.net/PG1Ha.png The desired structure should resemble the one shown in this image. I have made modificatio ...

How can we enhance our proxyURL in Kendo UI with request parameters?

As outlined in the Kendo UI API documentation, when using pdf.proxyURL with kendo.ui.Grid, a request will be sent containing the following parameters: contentType: Specifies the MIME type of the file base64: Contains the base-64 encoded file content fil ...

Using a Typescript enum within an Angular ng-click event

Currently, I am working with a TypeScript enum that looks like this: enum AuthState { New, Exist, Forgot }; In one of my .cshtml files (ASP.NET MVC), I have a button with an Angular ng-click attribute as follows: <a ng-click="MyClick(AuthState.New)"& ...

Is there a way to customize a carousel using media queries and remove it as needed?

I am facing an issue with displaying a row of images on my page depending on the window size. The images should be in a carousel if the window is 320px or below, but I want them to appear in a row if the window size is larger than 320px. Specifically, wh ...

Creating a Jest TypeScript mock for Axios

Within a class, I have the following method: import axios from 'axios' public async getData() { const resp = await axios.get(Endpoints.DATA.URL) return resp.data } My aim is to create a Jest test that performs the following actions: jes ...

Tips for creating a table in Angular 2

I need help creating a new row in a table using Angular. I know how to do it in pure Javascript, like the code below where addRow() method is called to generate a new row. But I'm new to Angular and want to learn the correct way to achieve this withou ...

Is it possible to define a unique function signature in a child class when implementing a method from a parent class?

In the process of developing a repository module that includes generic methods, I have found that as long as each derived class has the `tableName` configured, the basic query for creating, finding, or deleting records remains consistent across all child c ...

What is the best way to define this.someProperty in a React component using TypeScript?

I'm encountering an issue with TS2339: Property 'someProperty' does not exist on type ''. I am attempting to add a new property to my React component using this.someProperty. interface MyComponentState { allClear: boo ...

Activate jQuery Following an Ajax Request - Extension for Enhanced Navigation Using Ajax - WooCommerce Plugin

After searching extensively, I couldn't find a solution directly related to my issue. My knowledge of jQuery is limited, so I'm hoping the solution is something simple. Here is my situation... • I am using a WooCommerce website and have integ ...

Delivering a Captivating JavaScript Pop-Up upon Page Loading

I have a simple pop up window (with no content) that triggers with the 'onclick' event. How can I modify the code below to make the popup appear automatically when the page loads? <head> <title>Popup Display</title> < ...

Passing Parent Method to Child Component in React Native

I'm experiencing an issue trying to pass a method from my parent component to a child component. Although I believe my code is correct, I keep getting the error message undefined is not an object(evaluating '_this2.props.updateData'). Despit ...

troubleshooting ajax get request for js file in Rails with js.erb extension - addressing URL and naming issues

Within my profile/index.html.haml file, I currently have the following code: :javascript $(document).ready(function(){ $('#clickablething').click(function() { $.get('/profile', {**passed in json data**}, null, 'script& ...

Is there a way to load an image asynchronously when the page loads and show a loading gif during the loading process?

My image tag displays a dynamically generated graph from the database. The loading time can vary significantly, sometimes only taking a second while other times it may take up to 6 or 7 seconds for the graph image to appear. I am looking for a way to sho ...

exploring asynchronous javascript behavior utilizing the sleep/setTimeout function in the context of THREEJS and Angular

As a newcomer to Javascript and asynchronous programming, I am facing what I believe to be a beginner's issue. I have been using ThreeJS to create a scene with multiple objects (approximately 100) and everything was working smoothly until now. My cu ...

Setting up a collaborative Angular + Web API environment for multiple developers can be achieved by following these steps

I am curious about how to set up our development environments for Angular + .Net Core Web API with multiple developers. Each developer working on the project may use a different port locally for the API. This means we need individual local settings for ea ...

Conceal the scrollable content beneath a stationary transparent header, allowing the background to

Imagine having a background image, fixed header with transparent areas, a content div with semi-transparent background, and dynamic height in a traditional header/content/footer layout. The desired effect is to have the background and content scroll under ...

Is it considered best practice to include try/catch blocks within the subscribe function in RxJs?

Imagine we have an Angular 2 application. There is a service method that returns data using post(), with a catch() statement to handle any errors. In the component, we are subscribing to the Observable's data: .subscribe( ()=> { ...

Retrieving Data from Database Using Laravel and Ajax Post-Update

I am facing an issue with my edit form, designed for admins to edit book details. Upon submitting the form, the values are updated in the database successfully. However, the page fails to load the updated values into the form without requiring a refresh/re ...