Randall Jamison
Randall Jamison

Reputation: 329

jQuery Card Flip on Mouseenter/Mouseexit - triggering multiple times

The issue is that if you do the mouseenter and wiggle your mouse around fast, it will trigger the flipping action multiple times, making it flicker or look strange. Is there a better way to do what I'm doing here?

jQuery('.card').mouseenter(function(e) {
  e.stopPropagation();
  jQuery(this).addClass('flipped');
}).mouseleave(function(e) {
  e.stopPropagation();
  jQuery(this).removeClass('flipped');
});
.card {
  width: 150px;
  height: 300px;
  position: absolute;
  cursor: pointer;
  background-color: purple;
  /* Set the transition effects */
  -webkit-transition: -webkit-transform 0.4s;
  -moz-transition: -moz-transform 0.4s;
  -o-transition: -o-transform 0.4s;
  transition: transform 0.4s;
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  -o-transform-style: preserve-3d;
  transform-style: preserve-3d;
}

.card.flipped {
  -webkit-transform: rotateY( 180deg);
  -moz-transform: rotateY( 180deg);
  -o-transform: rotateY( 180deg);
  transform: rotateY( 180deg);
}

.card .front,
.card .back {
  display: block;
  height: 100%;
  width: 100%;
  text-align: center;
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
  -o-backface-visibility: hidden;
  backface-visibility: hidden;
  box-shadow: 3px 5px 20px 2px rgba(0, 0, 0, 0.25);
}

.card .front h3 {
  font-size: 30px;
}

.card .back p {
  height: 75px;
}

.card .front .card-text {
  padding: 0 25px;
  height: 100px;
}

.card .back {
  width: 100%;
  padding-left: 3%;
  padding-right: 3%;
  font-size: 16px;
  text-align: left;
  line-height: 25px;
  background-color: #ffffff;
  text-align: center;
  display: flex;
  align-items: center;
}

.card .back {
  -webkit-transform: rotateY( 180deg);
  -moz-transform: rotateY( 180deg);
  -o-transform: rotateY( 180deg);
  transform: rotateY( 180deg);
}

.card .apply-link {
  text-decoration: none;
  background-color: #fff;
  color: #000;
  padding: 8px 20px;
}

.card .back h3 {
  font-size: 24px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="card">
  <div class="front">
    <h3>Big Header</h3>
    <div class="card-text">Info text here</div>
  </div>
  <div class="back" style="background-color: #b24377">
    <h3>Up to 40% off</h3>
    <p>Text here </p>
    <a href="http://linkhere.com" class="apply-link">Apply Now</a>
  </div>
</div>

The issue is that if you do the mouseenter and wiggle your mouse around fast, it will trigger the flipping action multiple times, making it flicker or look strange. Is there a better way to do what I'm doing here?

Upvotes: 0

Views: 51

Answers (1)

ZIASH
ZIASH

Reputation: 135

One way to solve the issue is to add a wrapper around the card and listen to events on the wrapper instead of the card

jQuery('.wrapper').mouseenter(function(e) {
        e.stopPropagation();
        let $this = jQuery(this).find('.card');
        if(!$this.hasClass('flipped')){
          $this.addClass('flipped');
        }
}).mouseleave(function(e){
        e.stopPropagation();
        jQuery(this).find('.card').removeClass('flipped');
});
.wrapper{
 width: 150px;
  height: 300px;
 
}
.card {
  width: 100%;
  height: 100%;
  cursor: pointer;
  background-color: purple;
  
  
  /* Set the transition effects */
  -webkit-transition: -webkit-transform 0.4s;
  -moz-transition: -moz-transform 0.4s;
  -o-transition: -o-transform 0.4s;
  transition: transform 0.4s;
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  -o-transform-style: preserve-3d;
  transform-style: preserve-3d;
}

.card.flipped {
  -webkit-transform: rotateY( 180deg );
  -moz-transform: rotateY( 180deg );
  -o-transform: rotateY( 180deg );
  transform: rotateY( 180deg );
 
}

.card .front,
.card .back {
  display: block;
  height: 100%;
  width: 100%;
  text-align: center;
  position: absolute;

    display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;

  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
  -o-backface-visibility: hidden;
  backface-visibility: hidden;
  
  box-shadow: 3px 5px 20px 2px rgba(0, 0, 0, 0.25);
}

.card .front h3 {
    font-size: 30px;
}

.card .back p {
    height: 75px;
}

.card .front .card-text {
    padding: 0 25px;
    height: 100px;
}

.card .back {
  width: 100%;
  padding-left: 3%;
  padding-right: 3%;
  font-size: 16px;
  text-align: left;
  line-height: 25px;
  background-color: #ffffff;
  text-align: center;
  display: flex;
  align-items: center;
}

.card .back {
  -webkit-transform: rotateY( 180deg );
  -moz-transform: rotateY( 180deg );
  -o-transform: rotateY( 180deg );
  transform: rotateY( 180deg );
}

.card .apply-link {
    text-decoration: none;
    background-color: #fff;
    color: #000;
    padding: 8px 20px;
}

.card .back h3 {
    font-size: 24px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div class="card">
        <div class="front">
            <h3>Big Header</h3>
            <div class="card-text">Info text here</div>
        </div>
        <div class="back" style="background-color: #b24377">
            <h3>Up to 40% off</h3>
            <p>Text here </p>
            <a href="http://linkhere.com" class="apply-link">Apply Now</a>
        </div>
    </div>
</div>

Upvotes: 1

Related Questions