My goal is to utilize vanilla JavaScript to highlight the anchor that was clicked and then remove the highlighting from any previously highlighted anchor

Hello everyone, this is my first time posting here and I'm still trying to figure things out, so I appreciate your patience.

Currently, I am experimenting with vanilla JS to create a functionality where clicked anchors are highlighted while removing the highlight from previously selected anchors.

I'm encountering some issues with this feature and as a beginner, I'm still learning the ropes.

Here's a link to my CodePen

Below is the snippet of JS code related to this task. The links have a class of .nav-link and 'active' is supposed to manipulate them after being clicked.

window.onload = afterClick;


function afterClick(){
  let linkClass = document.querySelectorAll(".nav-link");
  
  linkClass.forEach(link => link.addEventListener("click", function(){
    if (link.classList.contains("active")) {
      link.classList.remove("active");  
    }
    link.classList.add("active");
  }));  
}

Thank you for your help and understanding!

Answer №1

If you want to achieve this without using the onload event, you can opt for the hashchange event instead. Here's how:

window.addEventListener("hashchange", () => {
  let hash = window.location.hash;
  if (hash) {
    let linkClass = document.querySelectorAll(".nav-link");
    linkClass.forEach(x => x.classList.remove("active"))
    document.querySelector('a[href="' + hash + '"]').classList.add("active");
  }
});

This code snippet will remove the active class from all links whenever there is a change in the URL hash:

linkClass.forEach(x => x.classList.remove("active"))

After that, it will add the active class only to the link with the corresponding hash:

document.querySelector('a[href="' + hash + '"]').classList.add("active");

Check out the Working Demo below:

window.addEventListener("hashchange", () => {
  let hash = window.location.hash;
  if (hash) {
    let linkClass = document.querySelectorAll(".nav-link");
    linkClass.forEach(x => x.classList.remove("active"))
    document.querySelector('a[href="' + hash + '"]').classList.add("active");
  }
});
#main-doc{font-family:Montserrat,sans-serif}#navbar{float:left;position:fixed;font-family:Montserrat,sans-serif;font-weight:700;min-width:230px;max-width:231px;height:100vh;background:url(https://image.freepik.com/free-vector/elegant-white-texture-background_23-2148431731.jpg);margin-top:-10px;margin-left:-10px;margin-right:40px;margin-bottom:25px;border:1px solid #000}#navbar header{padding:14px;font-size:1.8em;text-align:center;border:1px solid #000}#navbar a{display:block;color:#000;text-decoration:none;padding:15px;font-size:1.1em;text-align:center;border:1px solid #000;border-top:0}.main-section header{margin-left:30px;font-family:Notable,sans-serif;font-size:1.4rem}.main-section ul li{list-style-type:none;font-size:1.3em;padding-bottom:6px}.main-section{margin-left:230px;margin-right:50px;padding-top:20px}#main-doc{padding-bottom:60px}code{font-size:1rem;font-family:Montserrat,sans-serif}.active{color:orange!important;background-color:#00f!important}@media only screen and (max-width:425px){#navbar{max-width:425px;min-width:200px;position:relative;width:100vw;height:auto}.nav-link{margin-top:0;width:100vw}.main-section{margin-left:5px;margin-right:10px;padding-top:20px}.main-section ul{padding-left:5px}.navbar a{padding:0}}
<style>
  @import url('https://fonts.googleapis.com/css2?family=Montserrat&family=Notable&display=swap');
  @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@700&display=swap');
</style>
<!-- font-family: 'Montserrat', sans-serif;
font-family: 'Notable', sans-serif;      -->

<nav id="navbar">
  <header style="color: #FFDF01 ;background: url(https://img.freepik.com/free-photo/blue-with-vignette-marble-texture-background-with-copy-space_23-2148327728.jpg?size=626&ext=jpg)">Common Sharks</header>
  <a class="nav-link" href="#About_Sharks" id="aboutSharks">About Sharks</a>
  <a class="nav-link" href="#The_Great_White">The Great White</a>

Answer №2

The initial issue I came across is with your if loop:

if (link.classList.contains("active")) {
    link.classList.remove("active");  
  link.classList.add("active");
  }

This code block only works on an element that already has the "active" class, so it's currently not functioning as intended. By modifying the existing loop to remove the active class from other elements and then adding it to the clicked link, we can achieve the desired outcome:

window.onload = afterClick;

function afterClick() {
    let linkClass = document.querySelectorAll(".nav-link");
    // Add eventListener
    linkClass.forEach((originalLink) =>
        originalLink.addEventListener("click", function () {
            let linkElems = document.querySelectorAll(".nav-link");
            // Remove "active" class from other links
            linkElems.forEach((linkElem)=>{
                if (linkElem.classList.contains("active")) {
                    linkElem.classList.remove("active");
                }
            });
            // Add the "active" class to the clicked element
            originalLink.classList.add("active");    
        })
    );
}

I hope this explanation proves helpful! :)

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 load Javascript using AJAX with jQuery?

So I have this JavaScript code that I insert into a webpage using the following: <script type="text/javascript" src="http://ext.nicovideo.jp/thumb_watch/sm13154955?w=640&h=395"></script> It basically places an object/embed code into the w ...

What is the method for determining the data type of a column in an Excel sheet that has been

Currently, I am utilizing the XLSX npm library to convert an Excel sheet into JSON format. However, all of the retrieved data is currently being returned as strings. To see a demo of the XLSX read process, you can visit this Stackblitz demo Is there a w ...

Monitoring and refining console.error and console.log output in CloudWatch

I've encountered a situation where my lambda function includes both console.error and console.log statements, which Node.js interprets as stderr and stdout outputs respectively. However, upon viewing the logs in CloudWatch, I noticed that they appear ...

Using WEBGL to Showcase Your Images: A Step-by-Step Guide

I'm hoping to effortlessly showcase an image on the canvas at specific x and y co-ordinates using WEBGL, but I'm unsure of the process. Must shaders be included along with all other technical details? I've come across code snippets for displ ...

The expiration time and date for Express Session are being inaccurately configured

I'm experiencing an issue with my express session configuration. I have set the maxAge to be 1 hour from the current time. app.use( session({ secret: 'ASecretValue', saveUninitialized: false, resave: false, cookie: { secure ...

Utilizing React Typescript Discriminating Unions to choose between two different types based solely on props

In my project, I have a component that consists of different types: type Base = { color: string } type Button = { to: string } & Base type Link = { link: string linkNewTab: boolean } & Base type ComponentProps = Button | Link e ...

Empty MongoDB array persists even after POST request

After performing a POST request in Insomnia, my "games" array remains empty. What am I missing? UPDATE: New error after array.push({}) "errorValidationError: games.0.gameID: Path gameID is required., games.0.isGameActivated: Path isGameActivated is requi ...

Utilizing Jquery for draggable/droppable functionality in combination with custom overflow styles

Encountering a challenge with a drag and drop system that utilizes CSS overflow properties to enable vertical scrolling of a list of values. The issue arises when dragging an item between selected and unselected areas, causing the dragged item to disappear ...

Looking to add the Ajax response data into a dropdown selection?

Looking to add select options dynamically, but unsure how to retrieve response values. I am able to fetch all the values in the response, but I struggle with appending them correctly in the select option. I believe the syntax is incorrect. success: funct ...

The API response indicating success is simply denoted as "Success: True", without any accompanying data

I've set up my application on an express server with a proxy to communicate with the API server. Here's a snippet of my code: HTML: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> ...

React component is unable to identify prop

I'm attempting to send an array of objects from the main App.js file to a smaller component using props. However, for some reason, the prop is not being recognized within the smaller component file. https://i.stack.imgur.com/WuyFr.png https://i.stac ...

Custom palette in Material UI design palette allows users to create

Hey there everyone! I've been working on a website using ReactJS and Material UI, starting with this cool template. One thing I'm trying to do is change the color of the TextField when it's focused. Right now it's blue, but I want it ...

Tips for displaying multiple table rows when clicked

Looking to display two hidden rows at a time out of a total of 5 rows when a display button is clicked. Once the last 2 rows are displayed, the button should become disabled. Similar to a question on Stack Overflow, but unable to use the solution provided ...

What is the best way to justify list items to the left?

Having trouble aligning my list content to the left. Any suggestions are welcome! Here is a snippet of the code: <div class="col-md-4 mb-1"> <i class="fas fa-hiking fa-4x"></i> <h4 class="my-4" font-weight-bold&g ...

Issues with 'Backspace' and 'Clear' buttons on HTML calculator preventing proper function in JavaScript

Hello everyone! I've recently started working on a pure HTML/CSS/JS calculator project. While the HTML and CSS parts went smoothly, I'm facing some issues with getting the initial functions to work properly. Despite doing some research online, I ...

Enhance your website with a lightbox effect using FancyBox directly in your JavaScript code

I am currently experiencing an issue with implementing fancybox on my website. I have a website that features links to articles, which open in fancybox when clicked. The problem arises when a user tries to access an article directly. In this case, the use ...

Enhancing Vuejs Security: Best Practices and Tips for Secure Development

Recently, I developed a Web Application utilizing Vue.js and fetching data from the backend using 'vue-resource' in combination with Express and Postgres. Now, my main objective is to enhance its security by integrating an API Key. I am somewha ...

What is the best way to extract this content from the HTML using Selenium Webdriver?

My goal is to extract the text "1532.6788418669355" from this HTML code, but I've been facing challenges in doing so. Here's what I've attempted: IList options = Driver.FindElements(By.XPath(".//span//*")); Options[0].Text = "" There are n ...

Tab button that can be easily printed

I'm currently facing a challenge with my HTML code on my website. I have 5 tabs already set up, but I want to add one that redirects users to a printable page that opens the print menu specific to their browser. It seems like there might be an issue i ...

What is the most effective approach for managing nested callbacks in Node.js/Expressjs?

My server side coding is done using Node.js and Expressjs, with MongoDB as the backend. Although I am new to these technologies, I need to perform a list of actions based on requests. For example, in user management: Check if the user is already registe ...