1

I have a problem with a repeating CSS animation that is executed by a jquery hover function. You can see an example of the problem in this DEMO.

When you open the demo please hover over the first star and pan the mouse from left to right. As you can see the animation repeats itself causing a stutter. How can I fix this so that the animation only fire once per star, keeping the previous stars highlighted.

HTML

<div class="GvStarContainer">
  <!--Style 1 STARTED-->
  <div class="GvStarTmp">

    <div class="margi-star">
      <div class="rate-ex1-cnt">
        <div id="1" class="star star-one-1 rate-btn star-one"></div>
        <div id="2" class="star star-one-2 rate-btn star-one"></div>
        <div id="3" class="star star-one-3 rate-btn star-one"></div>
        <div id="4" class="star star-one-4 rate-btn star-one"></div>
        <div id="5" class="star star-one-5 rate-btn star-one"></div>
      </div>
    </div>
  </div>
  <!--Style 1 FINISHED-->
  <!--Style 2 STARTED-->
  <div class="GvStarTmp">

    <div class="margi-star">
      <div class="rate-ex2-cnt">
        <div id="1" class="star star-two-1 rate-btn star-two"></div>
        <div id="2" class="star star-two-2 rate-btn star-two"></div>
        <div id="3" class="star star-two-3 rate-btn star-two"></div>
        <div id="4" class="star star-two-4 rate-btn star-two"></div>
        <div id="5" class="star star-two-5 rate-btn star-two"></div>
      </div>
    </div>
  </div>
  <!--Style 2 FINISHED-->
  <!--Style 3 STARTED-->
  <div class="GvStarTmp">

    <div class="margi-star">
      <div class="rate-ex3-cnt">
        <div id="1" class="star star-tree-1 rate-btn star-tree"></div>
        <div id="2" class="star star-tree-2 rate-btn star-tree"></div>
        <div id="3" class="star star-tree-3 rate-btn star-tree"></div>
        <div id="4" class="star star-tree-4 rate-btn star-tree"></div>
        <div id="5" class="star star-tree-5 rate-btn star-tree"></div>
      </div>
    </div>
  </div>
  <!--Style 3 FINISHED-->
</div>

JS

$(document).ready(function() {

  var prevStars = $(this).prevAll();
  var nextStars = $(this).nextAll();

  $(".star").hover(
    function() {
      var prevStars = $(this).prevAll();
      prevStars.addClass('rate-btn-hover');
    },
    function() {
      var prevStars = $(this).prevAll();
      prevStars.removeClass('rate-btn-hover');
    }
  );

  $("body").on("click", ".star", function() {
    var prevStars = $(this).prevAll().addBack();
    prevStars.addClass('rate-btn-active');
  });
});
1
  • You could add some timeouts before adding and removing the classes. Commented Nov 1, 2016 at 10:51

2 Answers 2

1

You are applying the animation to both :hover selector and .rate-btn-hover class with this:

.rate-ex1-cnt .rate-btn:hover, .rate-ex1-cnt  .rate-btn-hover, .rate-ex1-cnt  .rate-btn-active{
    background: url(http://www.oobenn.com/GvStar/css/img/rate-btn1-hover.png) no-repeat;
    -webkit-animation-name: bounceIn;
    animation-name: bounceIn;
    -webkit-animation-duration: .75s;
    animation-duration: .75s
}

Instead apply the animation only to :hover selector

.rate-ex1-cnt .rate-btn:hover {
    background: url(http://www.oobenn.com/GvStar/css/img/rate-btn1-hover.png) no-repeat;
    -webkit-animation-name: bounceIn;
    animation-name: bounceIn;
    -webkit-animation-duration: .75s;
    animation-duration: .75s
}

and remove the animation properties from .rate-btn-hover class

.rate-ex1-cnt  .rate-btn-hover, .rate-ex1-cnt  .rate-btn-active{
    background: url(http://www.oobenn.com/GvStar/css/img/rate-btn1-hover.png) no-repeat;
}

See first star group in updated Demo.

Sign up to request clarification or add additional context in comments.

Comments

1

The problem seems to be that you are clearing the previous stars in the hover() 'handleOut' function. You want to retain those stars as filled, therefore you only want to clear 'next' stars, and then separately manage the cleanup of all stars as you exit the area containing the group of stars.

$(".star").hover(
    function() {
       $(this).prevAll().addClass('rate-btn-hover');
       $(this).addClass('rate-btn-hover');
    },
    function() {
       $(this).nextAll().removeClass('rate-btn-hover');
       $(this).removeClass('rate-btn-hover');
    }
);

$(".margi-star div:first-child").hover(
    function() {
    },
    function() {
       $(this).children().removeClass('rate-btn-hover');
    }
);

With this approach I am handling the start of the animation through script by setting the current controls class:

$(this).addClass('rate-btn-hover');

The difficulty with a pure css solution in your current code is that you are setting a background image in your .rate-btn:hover selector, but then the non hover state managed by .rate-btn has a different background image (empty star). This causes the filled star to be replaced with a blank star when .rate-btn:hover is no longer active.

As the css hover event is no longer required in my attempted fix, you can also remove the :hover selector from your css as follows:

.rate-ex1-cnt  .rate-btn-hover, .rate-ex1-cnt  .rate-btn-active{
    background: url(http://www.oobenn.com/GvStar/css/img/rate-btn1-hover.png) no-repeat;
    -webkit-animation-name: bounceIn;
    animation-name: bounceIn;
    -webkit-animation-duration: .75s;
    animation-duration: .75s
}

The full demo is here: http://codepen.io/anon/pen/VKorea

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.