How to keep link hover animation after clicking?

Viewed 169

I am trying to keep the link hover effect in place after clicking. This is what I currently have:

HTML:

    <div class="nav-desktop">
        <ul class="desktop-list">
            <li class="desktop-link"><a class="link is-active" href="index.html">Home</a></li>
            <li class="desktop-link"><a class="link" href="html/about.html">About</a></li>
            <li class="desktop-link"><a class="link" href="html/blog.html">Blog</a></li>
            <li class="desktop-link"><a class="link" href="html/projects.html">Projects</a></li>
            <li class="desktop-link"><a class="link" href="html/contact.html">Contact</a></li>
        </ul>
    </div>

CSS:

.link {
    color: var(--dracula-pink);
    padding: 5px 5px 5px 5px;
    margin-right: 5rem;
    text-decoration: none;
    font-size: 1.2rem;
    text-transform: uppercase;
    text-shadow: 0 2px 3px rgba(0, 0, 0, 0.4), 0 8px 13px rgba(0, 0, 0, 0.1), 0 18px 23px rgba(0, 0, 0, 0.1);
}

.link:hover {
    background-repeat: repeat-x;
    background-position: left 0% bottom -5%;
    background-image: linear-gradient(90deg, rgba(139, 233, 253, 1) 0%, rgba(189, 147, 249, 1) 50%, rgba(80, 250, 123, 1) 100%);
    background-size: 100% 18%;
    transition: ease-in 0.2s;
}

.link.is-active {
    background-repeat: repeat-x;
    background-position: left 0% bottom -5%;
    background-image: linear-gradient(90deg, rgba(139, 233, 253, 1) 0%, rgba(189, 147, 249, 1) 50%, rgba(80, 250, 123, 1) 100%);
    background-size: 100% 18%;
}

JS:

const link = document.querySelector(".link");
link.addEventListener("click", toggleActive);

function toggleActive() {
    link.classList.toggle("is-active");
};

I know I will have to add something to remove the effect from the previous link, but I can't even get this part down after every variation I can think of.

2 Answers

You are using el.querySelector() which will only return the first matching element found. You need to get the entire nodeList of the elements selector, use el.querySelectorAll() then run the nodeList through a loop and place your function in an eventListener. Since you want to remove the active class, there are multiple ways to do this. I did it by simply removing it from all elements using the el.forEach loop and then set the classList on the event.target of the event with in the function.

You could use a conditional to check which element has the active class and then toggle/remove it on click as well but that would be a bit more code in your function.

EDITS: OP wants to determine which link has been pressed on another page once the href has sent them to that page. In this case there is no need for JS, just statically set the class in the corresponding page button within that pages HTML.

If you really want to use JS, you can add an id to the body tag on each page, ie on contact page --> <body id="Contact"> that corresponds with the textContact of each of your navs page link button. Then using JS, get rid of the eventListener and simply look for the body.id and if it equals the link.textContent in the loop over the nodeList set the active class.

links.forEach(link => document.body.id === link.textContent ? link.classList.add("is-active") : null)

User clicks About on about.html

^^^^^^^^^^^^^^^^^^^^^

<li class="desktop-link is-active"><a class="link" href="html/about.html">About</a></li>

Here is the answer to the original question:

//--> you need to get all the elements in the nodeList 
//--> with the class .link --> querySelectorAll()
const links = document.querySelectorAll(".link");
//--> loop over these elements and add the eventListener 
links.forEach(link => document.body.id === link.textContent ? link.classList.add("is-active") : null)
.link {
  color: var(--dracula-pink);
  padding: 5px 5px 5px 5px;
  margin-right: 5rem;
  text-decoration: none;
  font-size: 1.2rem;
  text-transform: uppercase;
  text-shadow: 0 2px 3px rgba(0, 0, 0, 0.4), 0 8px 13px rgba(0, 0, 0, 0.1), 0 18px 23px rgba(0, 0, 0, 0.1);
}

.link:hover {
  background-repeat: repeat-x;
  background-position: left 0% bottom -5%;
  background-image: linear-gradient(90deg, rgba(139, 233, 253, 1) 0%, rgba(189, 147, 249, 1) 50%, rgba(80, 250, 123, 1) 100%);
  background-size: 100% 18%;
  transition: ease-in 0.2s;
}

.link.is-active {
  background-repeat: repeat-x;
  background-position: left 0% bottom -5%;
  background-image: linear-gradient(90deg, rgba(139, 233, 253, 1) 0%, rgba(189, 147, 249, 1) 50%, rgba(80, 250, 123, 1) 100%);
  background-size: 100% 18%;
}
<body id="Home">
<div class="nav-desktop">
  <ul class="desktop-list">
    <li class="desktop-link"><a class="link" href="#?is-active">Home</a></li>
    <li class="desktop-link"><a class="link" href="#?is-active">About</a></li>
    <li class="desktop-link"><a class="link" href="#?is-active">Blog</a></li>
    <li class="desktop-link"><a class="link" href="#?is-active">Projects</a></li>
    <li class="desktop-link"><a class="link" href="#?is-active">Contact</a></li>
  </ul>
</div>

I think that the guys above misunderstood the requirement.

First, this is a menu mining that when you click on the link there will be a redirect on the page.

You have then to find out which Site/Page you are currently on and then select the current link in the menu.

Make sure to ask if there is something you don't understand

Here is my solution.

// this should be on a masterPage alt all pages
const link = document.querySelectorAll(".nav-desktop .link");
var href = window.location.href;

link.forEach(x=> {
  // Now look at the href of the page an compare it with your menu then select the current(right) link
  if (!href || href =="" || href =="/")
      {
        // if its empty then select the first one eg the default index.html
        if (x.getAttribute("href") == "index.html")
            x.classList.add("is-active");
      }else if (href.toLowerCase().indexOf(x.getAttribute("href").toLowerCase()) != -1)
            x.classList.add("is-active");
});
.link {
  color: var(--dracula-pink);
  padding: 5px 5px 5px 5px;
  margin-right: 5rem;
  text-decoration: none;
  font-size: 1.2rem;
  text-transform: uppercase;
  text-shadow: 0 2px 3px rgba(0, 0, 0, 0.4), 0 8px 13px rgba(0, 0, 0, 0.1), 0 18px 23px rgba(0, 0, 0, 0.1);
}

.link:hover {
  background-repeat: repeat-x;
  background-position: left 0% bottom -5%;
  background-image: linear-gradient(90deg, rgba(139, 233, 253, 1) 0%, rgba(189, 147, 249, 1) 50%, rgba(80, 250, 123, 1) 100%);
  background-size: 100% 18%;
  transition: ease-in 0.2s;
}

.link.is-active {
  background-repeat: repeat-x;
  background-position: left 0% bottom -5%;
  background-image: linear-gradient(90deg, rgba(139, 233, 253, 1) 0%, rgba(189, 147, 249, 1) 50%, rgba(80, 250, 123, 1) 100%);
  background-size: 100% 18%;
}
<div class="nav-desktop">
  <ul class="desktop-list">
    <li class="desktop-link"><a class="link is-active" href="index.html">Home</a></li>
    <li class="desktop-link"><a class="link" href="html/about.html">About</a></li>
    <li class="desktop-link"><a class="link" href="html/blog.html">Blog</a></li>
    <li class="desktop-link"><a class="link" href="html/projects.html">Projects</a></li>
    <li class="desktop-link"><a class="link" href="html/contact.html">Contact</a></li>
  </ul>
</div>

Related