Search code examples
javascripthtmlhovercursormouseover

How to add a class on hover of an anchor tag


I have added a custom cursor to my site but I cannot figure out how to change the cursor styles on mouseenter/mouseleave of an anchor tag. I can only get it to work on the first anchor tag when using .getElementsbyClassName. I am trying to apply .cursor-hover to .cursor and .cursor-outline-hover to .cursor-outline on mouseenter and remove the styles on mouseleave.

const cursor = document.querySelector('.cursor');
const cursor_outline = document.querySelector('.cursor-outline');

document.addEventListener('mousemove', e => {
  cursor.setAttribute("style", "top: "+(e.pageY - 5)+"px; left: "+(e.pageX - 5)+"px;");
})

document.addEventListener('mousemove', e => {
  cursor_outline.setAttribute("style", "top: "+(e.pageY - 25)+"px; left: "+(e.pageX - 25)+"px;");
})

document.addEventListener('click', () => {
  cursor.classList.add("cursor-click");

  setTimeout(() => {
    cursor.classList.remove("cursor-click");
  }, 300)
}) 
html {
  font-family: Helvetica, Arial, sans-serif;
}

body {
  background-color: #2E1C33;
  position: relative;
}

body,
html {
  margin: 0;
  padding: 0;
}

* {
  cursor: none;
  box-sizing: border-box;
}

.cursor,
.cursor-outline {
  pointer-events: none;
}

.cursor {
  width: 10px;
  height: 10px;
  background-color: #35E8C6;
  border-radius: 50%;
  position: absolute;
  z-index: 300;
}

.cursor-outline {
  width: 50px;
  height: 50px;
  position: absolute;
  background-color: black;
  border-radius: 50%;
  opacity: 0.5;
  transition-duration: 200ms;
  transition-timing-function: ease-out;
  z-index: 290;
}

.cursor-click {
  background: #FF5869;
  animation: cursor-clickAnim 0.6s forwards;
}

@keyframes cursor-clickAnim {
  from {
    transform: scale(1);
  }

  to {
    transform: scale(1.8);
  }
}

.cursor-outline-hover {
  background-color: rgba(255, 255, 255, 0);
  transform: scale(1.3);
  border: 1px solid white;
  opacity: 1;
}

.cursor-hover {
  background-color: white;
}

a {
  text-decoration: none;
  color: white;
}

a:hover {
  text-decoration: none;
}

section {
  margin: 0;
  padding: 0;
  padding: 0 15em;
  width: 100vw;
  max-width: 100%;
  height: 100vh;
  color: white;
  display: flex;
  align-items: center;
}

p {
  font-size: 1.5em;
  letter-spacing: 0.05em;
  line-height: 1.8;
  color: #F4CEFF;
}

h1 {
  text-transform: uppercase;
  font-weight: 700;
  letter-spacing: 0.3em;
  font-size: 4em;
  line-height: 1.5;
  margin-bottom: 0.3em;
  margin-top: 0;
}

h2,
h3 {
  text-transform: uppercase;
  font-weight: 500;
  letter-spacing: 0.4em;
  font-size: 1.2em;
  color: #35E8C6;
}

h3 {
  color: white;
}

h4 {
  text-transform: uppercase;
  font-weight: 700;
  letter-spacing: 0.4em;
  font-size: 6em;
  margin: 1em 0;
  padding: 0;
}

.hero {
  display: flex;
  align-items: center;
}

.hero-inner h1 {
  margin-top: 0;
}

.hero h2 {
  font-family: 'Playfair-Display', 'Times', serif;
  text-transform: none;
  font-style: italic;
  font-weight: 500;
  font-size: 2em;
  margin: 0;
  letter-spacing: normal;
  color: white;
}

.btn-pill {
  text-decoration: none;
  color: #17473E;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  line-height: 45px;
  display: inline-block;
  background-color: #35E8C6;
  border-radius: 100em;
  width: 220px;
  text-align: center;
  letter-spacing: 0.1em;
  border: 2px solid #35E8C6;
  margin-top: 4em;
}

.btn-pill:hover,
.btn-alt:active,
.btn-alt:focus {
  background-color: #004E51;
  color: white;
}

.btn-main:hover,
.btn-main:active,
.btn-main:focus {
  background-color: #0A9F86;
  border: 2px solid #0A9F86;

}

.btn:focus,
.btn:active {
  outline: none;
  box-shadow: none;
}

.btn-alt {
  border: 2px solid #FF5869;
  background: none;
  color: #FF5869;
}

.btn-alt:hover,
.btn-alt:active,
.btn-alt:focus {
  background-color: #FF5869;
  color: #fff;
  box-shadow: none;
}

.hero .btn-alt {
  margin-left: 2em;
}

.hero .btn-main {
  display: inline-block;
  margin-right: 0.9em;
}

.hero-inner a i {
  font-size: 1.5em;
  vertical-align: middle;
  padding-left: 8px;
}
<html lang="en">
  <head>
    <link href="css/style.css" rel="stylesheet">
  </head>

  <body>
    <div class="cursor"></div>
    <div class="cursor-outline"></div>

    <section class="hero">

      <div class="hero-inner">

        <a type="button" href="" class="btn-primary btn-pill btn-main hover-item">Learn More</a>
        <a type="button" href="" class="btn-primary btn-pill btn-alt hover-item">Contact <i class="fas fa-long-arrow-alt-right"></i></a>
      </div>
    </section>
    <script type="text/javascript" src="js/script.js"></script>

  </body>

</html>

Any help would be much appreciated.


Solution

  • we can add events to each a tag like this:

    (Note, we create an array of all a tag elements using spread operator and querySelectorAll, then we re-assign (that's why we used let and not const) that array to a copy of that array with modifications - i.e. the same array but with each element now also having two event listeners attached. We do this by using the map function on the array - which doesn't change the array in place, hence re-assignment needed)

    let a_tags = [...document.querySelectorAll('a')];
    
    a_tags = a_tags.map((child,index) => {
      child.addEventListener('mouseover', (e) => {
        console.log(e.target);
        //Do something here with either the a tag or the cursor etc.
        //e.g.
        cursor.setAttribute('class', 'cursor-hover');
        cursor_outline.setAttribute('class', 'cursor-outline-hover');
      })
      child.addEventListener('mouseout', (e) => {
        console.log(e.target);
        //Do something here with either the a tag or the cursor etc.
        //e.g.
        cursor.setAttribute('class', 'cursor');
        cursor_outline.setAttribute('class', 'cursor-outline');
      })
      return child;
    })
    

    Does that help you? You just need to replace the code below the comments with however you exactly want to change the cursor and/or a tag etc? (I think I understood from your question but I am not 100% sure)

    const cursor = document.querySelector('.cursor');
    const cursor_outline = document.querySelector('.cursor-outline');
    
    document.addEventListener('mousemove', e => {
      cursor.setAttribute("style", "top: "+(e.pageY - 5)+"px; left: "+(e.pageX - 5)+"px;");
    })
    
    document.addEventListener('mousemove', e => {
      cursor_outline.setAttribute("style", "top: "+(e.pageY - 25)+"px; left: "+(e.pageX - 25)+"px;");
    })
    
    document.addEventListener('click', () => {
      cursor.classList.add("cursor-click");
    
      setTimeout(() => {
        cursor.classList.remove("cursor-click");
      }, 300)
    })
    
    let a_tags = [...document.querySelectorAll('a')];
    
    a_tags = a_tags.map((child,index) => {
      child.addEventListener('mouseover', (e) => {
        console.log(e.target);
        //Do something here with either the a tag or the cursor etc.
        //e.g.
        cursor.setAttribute('class', 'cursor-hover');
        cursor_outline.setAttribute('class', 'cursor-outline-hover');
      })
      child.addEventListener('mouseout', (e) => {
        console.log(e.target);
        //Do something here with either the a tag or the cursor etc.
        //e.g.
        cursor.setAttribute('class', 'cursor');
        cursor_outline.setAttribute('class', 'cursor-outline');
      })
      return child;
    })
    html {
      font-family: Helvetica, Arial, sans-serif;
    }
    
    body {
      background-color: #2E1C33;
      position: relative;
    }
    
    body,
    html {
      margin: 0;
      padding: 0;
    }
    
    * {
      cursor: none;
      box-sizing: border-box;
    }
    
    .cursor,
    .cursor-outline {
      pointer-events: none;
    }
    
    .cursor {
      width: 10px;
      height: 10px;
      background-color: #35E8C6;
      border-radius: 50%;
      position: absolute;
      z-index: 300;
    }
    
    .cursor-outline {
      width: 50px;
      height: 50px;
      position: absolute;
      background-color: black;
      border-radius: 50%;
      opacity: 0.5;
      transition-duration: 200ms;
      transition-timing-function: ease-out;
      z-index: 290;
    }
    
    .cursor-click {
      background: #FF5869;
      animation: cursor-clickAnim 0.6s forwards;
    }
    
    @keyframes cursor-clickAnim {
      from {
        transform: scale(1);
      }
    
      to {
        transform: scale(1.8);
      }
    }
    
    .cursor-outline-hover {
      background-color: rgba(255, 255, 255, 0);
      transform: scale(1.3);
      border: 1px solid white;
      opacity: 1;
    }
    
    .cursor-hover {
      background-color: white;
    }
    
    a {
      text-decoration: none;
      color: white;
    }
    
    a:hover {
      text-decoration: none;
    }
    
    section {
      margin: 0;
      padding: 0;
      padding: 0 15em;
      width: 100vw;
      max-width: 100%;
      height: 100vh;
      color: white;
      display: flex;
      align-items: center;
    }
    
    p {
      font-size: 1.5em;
      letter-spacing: 0.05em;
      line-height: 1.8;
      color: #F4CEFF;
    }
    
    h1 {
      text-transform: uppercase;
      font-weight: 700;
      letter-spacing: 0.3em;
      font-size: 4em;
      line-height: 1.5;
      margin-bottom: 0.3em;
      margin-top: 0;
    }
    
    h2,
    h3 {
      text-transform: uppercase;
      font-weight: 500;
      letter-spacing: 0.4em;
      font-size: 1.2em;
      color: #35E8C6;
    }
    
    h3 {
      color: white;
    }
    
    h4 {
      text-transform: uppercase;
      font-weight: 700;
      letter-spacing: 0.4em;
      font-size: 6em;
      margin: 1em 0;
      padding: 0;
    }
    
    .hero {
      display: flex;
      align-items: center;
    }
    
    .hero-inner h1 {
      margin-top: 0;
    }
    
    .hero h2 {
      font-family: 'Playfair-Display', 'Times', serif;
      text-transform: none;
      font-style: italic;
      font-weight: 500;
      font-size: 2em;
      margin: 0;
      letter-spacing: normal;
      color: white;
    }
    
    .btn-pill {
      text-decoration: none;
      color: #17473E;
      font-size: 12px;
      font-weight: 700;
      text-transform: uppercase;
      line-height: 45px;
      display: inline-block;
      background-color: #35E8C6;
      border-radius: 100em;
      width: 220px;
      text-align: center;
      letter-spacing: 0.1em;
      border: 2px solid #35E8C6;
      margin-top: 4em;
    }
    
    .btn-pill:hover,
    .btn-alt:active,
    .btn-alt:focus {
      background-color: #004E51;
      color: white;
    }
    
    .btn-main:hover,
    .btn-main:active,
    .btn-main:focus {
      background-color: #0A9F86;
      border: 2px solid #0A9F86;
    
    }
    
    .btn:focus,
    .btn:active {
      outline: none;
      box-shadow: none;
    }
    
    .btn-alt {
      border: 2px solid #FF5869;
      background: none;
      color: #FF5869;
    }
    
    .btn-alt:hover,
    .btn-alt:active,
    .btn-alt:focus {
      background-color: #FF5869;
      color: #fff;
      box-shadow: none;
    }
    
    .hero .btn-alt {
      margin-left: 2em;
    }
    
    .hero .btn-main {
      display: inline-block;
      margin-right: 0.9em;
    }
    
    .hero-inner a i {
      font-size: 1.5em;
      vertical-align: middle;
      padding-left: 8px;
    }
    <html lang="en">
      <head>
        <link href="css/style.css" rel="stylesheet">
      </head>
    
      <body>
        <div class="cursor"></div>
        <div class="cursor-outline"></div>
    
        <section class="hero">
    
          <div class="hero-inner">
    
            <a type="button" href="" class="btn-primary btn-pill btn-main hover-item">Learn More</a>
            <a type="button" href="" class="btn-primary btn-pill btn-alt hover-item">Contact <i class="fas fa-long-arrow-alt-right"></i></a>
          </div>
        </section>
        <script type="text/javascript" src="js/script.js"></script>
    
      </body>
    
    </html>