Apply the "active" class to the list item when its corresponding section is in view

I have a webpage with at least four sections. My goal is to dynamically apply the active class to the corresponding menu item when scrolling through each section. For instance, if the "About Us" section is visible on the screen, I want to mark the corresponding menu item as active. The same goes for other sections such as Gallery and Contact Us.

In addition to adding the active class, I also need to change the color and add a bottom border to the active menu item. It's important to note that I prefer not to rely on any external plugins or libraries.

You can check out this example where the active class and styles are applied to the navigation list:

Would it be feasible to achieve this functionality using jQuery?

Answer №1

Hey there! In the code snippet below, I've created a function named activateLink that assigns IDs to links. When a link is clicked, this function adds an active class to the corresponding list item using jQuery.

$(function() {
  $('.smothscrollclass a[href*="#"]:not([href="#"])').click(function() {
    if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') && location.hostname == this.hostname) {
      var target = $(this.hash); 
      target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
      if (target.length) {
        $('html, body').animate({
          scrollTop: target.offset().top - 100
        }, 1000);
        return false;
      }
    }
  });
});

// The activateLink function
function activateLink (link, section) {
if(section){
    $('html, body').animate({
        'scrollTop' : $("#"+section).position().top
    }, function(){    
       $(".active").removeClass("active");
       $("#"+link).addClass("active");
    });
}else{
 $(".active").removeClass("active");
 $("#"+link).addClass("active");
}
}

// Helper function to check section visibility and update active link
function checkSectionExistance(sectionId, linkId) {
 var element = document.querySelector('#'+sectionId);
var position = element.getBoundingClientRect();

// checking for partial visibility
if(position.top < window.innerHeight && position.bottom >= 0) {
$(".active").removeClass("active");
 $("#"+linkId).addClass("active");
}
}

// Event listener for scroll event
window.addEventListener('scroll', function() {

  checkSectionExistance('aboutus','about-link');
  checkSectionExistance('service','service-link');
  checkSectionExistance('gallery','gallery-link');
  checkSectionExistance('contactus','contact-link');
});
// CSS styles
body {
 // CSS styles here...
}

// More CSS styles...

.active {
border-bottom: 1px solid white;
}
<!-- HTML code goes here... -->

If you have any questions or need further clarification, feel free to let me know!

Answer №2

To achieve this using vanilla JavaScript, you can utilize the document.body.scrollTop; to determine the scroll position. Next, remove the 'active' style from all list items and apply it to the current item. You can do this manually for each item or use a loop like so:

for(let i = 0; i < liClass.length; i++){liClass[i].classList.remove("active")}
. Then, add the 'active' class to the current target by selecting it with an ID or unique class. This process works effectively for me. For jQuery, the concept is similar, just replace $("body").scrollTop().

Answer №3

I made some upgrades and now everything is super clear ;)

When it comes to scrolling, I utilized pure HTML by simply adding an ID to the element where you want to scroll and then including <a href="#theIdOfElement">

The classes were implemented using jQuery as per your request

2nd UPDATE:

let  x=0;
$(document).ready(()=>{
  $("a").click((e)=>{
    //Removes class active from all a-s and all divs
    $("a").removeClass("active");
    $("div").removeClass("active");
    //Adds only to clicked one
    $(e.target).addClass("active");

    //Adds class active to divs that contain the text on which you clicked
    $("div:contains("+ $(e.target).text() +")").addClass("active");
  });
$(document).scroll(()=>{
    $("p").text( $(document).scrollTop());
        if($(document).scrollTop() >= 970){
        //If you want to get style permenent remove line below
    $("div").removeClass("active");
    $("#contacts").addClass("active");
  }
      else if($(document).scrollTop() >= 508){
     //If you want to get style permenent remove line below
    $("div").removeClass("active");
    $("#about").addClass("active");
  }
  else if($(document).scrollTop() >= 8){
     //If you want to get style permenent remove line below
    $("div").removeClass("active");
    $("#home").addClass("active");
  }


  });
})
/*This is for smooth scrolling*/
html {
  scroll-behavior: smooth;
}
.big {
  height: 500px;
  width: 100%;
  border: solid black 1px;
}
.active {
color:red;
}
<div id="main">
<div style="position:fixed;display:flex;justify-content:flex-end;width:100%">
  <p id="demo">0</p>
<a href="#home">Home</a>
<a href="#about">About Us</a>
<a href="#contacts">Contacts</a>
</div>
<div class="big" id ="home">Home</div>
<div class="big" id ="about">About Us</div>
<div class="big" id ="contacts">Contacts</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  

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

Navigating race conditions within Node.js++]= can be challenging, but there are strategies

In the process of developing a MERN full stack application, I encountered a scenario where the frontend initiates an api call to "/createDeckOfCards" on my NodeJS backend. The main objective is to generate a new deck of cards upon clicking a button and the ...

While working on my Laravel and Vue.js project, I encountered the following error message: "Module not found: Error: Can't resolve './vue/app' in 'C:vue odolist esourcesjs'"

Running into an issue where the app.vue file cannot be found in the app.js. I'm using Laravel version "8.31.0" and VueJS version "^2.6.12". Any assistance would be highly appreciated. The content of app.js is: require('./bootstrap'); impor ...

Is there a way to implement retry functionality with a delay in RxJs without resorting to the outdated retryWhen method?

I'd like to implement a retry mechanism for an observable chain with a delay of 2 seconds. While researching, I found some solutions using retryWhen. However, it appears that retryWhen is deprecated and I prefer not to use it. The retry with delay s ...

I tried moving the onchange(this) function from HTML to JavaScript, but I seem to have missed a parameter. The code ends

I'm currently building a website for a fictional ice cream shop to enhance my JavaScript skills. function hideAAndB() { var pickupDiv = document.getElementById("pickupDiv"); var deliveryDiv = document.getElementById("deliveryDiv"); pickupDi ...

Exploring Angular Factory: Creating the getAll method for accessing RESTful APIs

In my Angular.JS factory, I am retrieving data from a REST Api. The REST Api endpoint is "/api/getSsls/1", where 1 represents the page number. The API response is in JSON format and contains the first ten items along with total pages/items information. I ...

Why does adding to an array in the Vuex store replace all existing values with the last entry?

Utilizing vuex-typescript, here is an example of a single store module: import { getStoreAccessors } from "vuex-typescript"; import Vue from "vue"; import store from "../../store"; import { ActionContext } from "vuex"; class State { history: Array<o ...

Is there a way to insert animated images in front of every navigation menu item?

I have successfully implemented the HTML and CSS for my navigation menu items, but now I'm facing an issue trying to incorporate unique images right before each menu item in WordPress. Due to the hover animation on the menu names, I couldn't get ...

Navigate to a particular row in jsgrid

I've implemented JS Grid for rendering data in a grid view from . The grid I'm using has multiple pages. I need to navigate to the page that includes the newly inserted row and highlight it after insertion. Is there an option in jsgrid that allo ...

When scraping daily HTML tables with Selenium, I am only able to retrieve the last page

Exploring web scraping to gather data for my latest project has been quite the adventure. This is my first attempt at extracting information from websites, specifically prices that are listed on a website. The challenge I am facing is that I require this d ...

Circular Profile Image

I am currently developing an application that features a home screen displaying a client's biography. I am working on creating a header that will have a title and a circular display image. In the code, I have used 3 divs to hold the wrapper, title, an ...

Interactive bar chart that updates in real-time using a combination of javascript, html, and

Current Situation: I am currently in the process of iterating through a machine learning model and dynamically updating my "divs" as text labels. My goal is to transform these values into individual bars that visually represent the values instead of just d ...

Struggling with an issue in React and Bootstrap4 while developing an application with create-react-app

In my experience with Windows 10, I encountered two scenarios where I faced problems. The first scenario involved creating applications using the create-react-app command and installing it with npm i -g [email protected]. Scenario 1 I stopped the React s ...

Improperly aligned rotation using tween.js and three.js

Utilizing three.js and tween.js, my goal is to develop a Rubik's cube made up of 27 small cubes grouped together for rotation by +Math.PI/2 or -Math.PI/2. To ensure smooth rotation, I am implementing the tween library. The specific issue I encounter ...

Troubleshoot: Issue with Multilevel Dropdown Menu Functionality

Check out the menu at this link: The issue lies with the dropdown functionality, which is a result of WordPress's auto-generated code. Css: .menu-tophorizontalmenu-container { margin: 18px auto 21px; overflow: hidden; width: 1005px; ...

Technique for updating URL when submitting a form on a webpage

I'm a newcomer to the world of coding and I have a simple issue that needs fixing. I want to create a form field where users can input the last segment of a URL provided to them. After entering this segment, I want the page to refresh automatically a ...

Differences Between APP_INITIALIZER and platformBrowserDynamic with provide

I've discovered two different approaches for delaying an Angular bootstrap until a Promise or Observable is resolved. One method involves using APP_INITIALIZER: { provide: APP_INITIALIZER, useFactory: (configService: ConfigurationService) => ( ...

What is the reason that property spreading is effective within Grid components but not in FormControl components?

Explore the sandbox environment here: https://codesandbox.io/s/agitated-ardinghelli-fnoj15?file=/src/temp4.tsx:0-1206. import { FormControl, FormControlProps, Grid, GridProps } from "@mui/material"; interface ICustomControlProps { gridProps?: ...

What is the functionality of ng-repeat in AngularJS when used outside the "jump" table?

Currently, I am in the process of constructing a layout using a table with nested ng-repeat. <div ng-controller="PresetManageController"> <table> <in-preset ng-repeat="preset in presetManage.presets"></in-preset> </table ...

Having difficulty aligning divs in the center

My nested div is causing alignment issues and I can't seem to solve it. Despite trying various solutions like margin: 0 auto and setting a specific width, the centering problem persists. Can someone please help me identify the issue and provide a fix ...

Refreshing the webpage without reloading using Ajax ResponseText

While the form successfully sends data to the MySQL database, it is unable to display the responseText within the specified <div id="ajaxGetUserServletResponse"></div>. How can I retrieve the response? <form id="form-id" class="ajaxform" ac ...