skip to Main Content

I want to make the heart icon move up, turn red, move back down, and turn back to black when I click on it. I also want to keep track of how many times I’ve clicked on it.

My html

<div class="center">
  <i class="fa-regular fa-heart" onclick="heartAnimation()"></i>
  <p id="count">0</p>
</div>;

My css

@keyframes heart {
  40% {
    transform: translateY(-10px);
    color: red;
  }
  95% {
    transform: translateY(0px;);
    color: red;
  }
  100% {
    color: black;
  }
}

.animation {
  animation: heart 1s;
}

My Javascript

const icon = document.querySelector(".fa-regular");
const count = document.querySelector("#count");
count = 0;

function heartAnimation() {
  icon.classList.add("animation");
  count.innerText++;
}

I originally thought that I could add an onclick listener to the icon and add a class that would call the keyframe and keep count of the clicks. The click counter works fine, but I want it so that the animation is called every time that I click it. Right now, it moves up and down only on the first click. After that, the heart icon doesn’t move or change color – only the click counter changes.

2

Answers


  1. you can do this through adding and removing animation class at the desired time.

    to do this you can use jquery code:

    $("someElement").addClass("className")
    $("someElement").removeClass("className")
    

    or javascript (vanilla/pure):

    document.getElementById("someElementID").classList.add("className")
    document.getElementById("someElementID").classList.remove("className")
    

    also if you need special times for your animation to kick in or to be removed you need to use events and functions like scroll height, timeout, interval, onclick, .etc

    Login or Signup to reply.
  2. Couple of things:

    1. You assign count as a constant for the first node in the node list that returns an id of count. Then you redefine it as 0 and try to increment it later in your function.
      • use a number let num = 0; for the incrementing and then assign the number to the nodes textContent once you increment it from its previous value.
    2. As a commentor said you can use a setTimeout to correspond with the timing of your animation. Inside the timeout remove your animation class.
    setTimeout(()=>{
        icon.classList.remove("animation");
      },1000)
    

    Optionally you could also add a pointer-event in the CSS to remove any clicks while the animation is playing. You could also code in logic that would store the click and reset the animation on click.

    Lastly I prefer adding event listeners using .addEventListener method.

    Some important notes about .addEventListener vs onclick= from (MDN)

    • It allows adding more than one handler for an event. This is particularly useful for libraries, JavaScript modules, or any other kind of code that needs to work well with other libraries or extensions.
    • In contrast to using an onXYZ property, it gives you finer-grained control of the phase when the listener is activated (capturing vs. bubbling).
    • It works on any event target, not just HTML or SVG elements.
    const icon = document.querySelector(".fa-regular");
    let count = document.querySelector("#count");
    let num = 0;
    
    function heartAnimation() {  
      icon.classList.add("animation");
      num++;
      count.textContent = num;
      setTimeout(() => icon.classList.remove("animation"), 1000);
    }
    
    icon.addEventListener('click', heartAnimation);
    .animation {
      animation: heart 1s;
      /* runs a bit smoother is we let the animtation play out before allowing user to click again. Set pointer-events to none you can remove the pointer-events if you want to allow users to click before the animation ends */
      pointer-events: none;
    }
    
    @keyframes heart {
      40% {
        transform: translateY(-10px);
        color: red;
      }
      95% {
        transform: translateY(0px;);
        color: red;
      }
      100% {
        color: black;
      }
    }
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" rel="stylesheet"/>
    <div class="center">
      <i class="fa-regular fa-heart"></i>
      <p id="count">0</p>
    </div>;
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search