Home > database >  jQuery Card Flip on Mouseenter/Mouseexit - triggering multiple times
jQuery Card Flip on Mouseenter/Mouseexit - triggering multiple times

Time:02-01

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 >
        <div >
            <h3>Big Header</h3>
            <div >Info text here</div>
        </div>
        <div  style="background-color: #b24377">
            <h3>Up to 40% off</h3>
            <p>Text here </p>
            <a href="http://linkhere.com" >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?

CodePudding user response:

  1. There is no need to use jQuery for this, pure CSS can handle this.
  2. The vendor prefixes are no longer necessary in your case.
  3. The "wiggle effect" is the expected behavior.

Try this

.card {
  width: 150px;
  height: 300px;
  position: absolute;
  cursor: pointer;
  background-color: purple;
  transition: transform 0.4s;
  transform-style: preserve-3d;
}

.card:hover {
  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;
  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 {
  transform: rotateY( 180deg);
}

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

.card .back h3 {
  font-size: 24px;
}
<div >
  <div >
    <h3>Big Header</h3>
    <div >Info text here</div>
  </div>
  <div  style="background-color: #b24377">
    <h3>Up to 40% off</h3>
    <p>Text here </p>
    <a href="http://linkhere.com" >Apply Now</a>
  </div>
</div>

CodePudding user response:

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 >
<div >
        <div >
            <h3>Big Header</h3>
            <div >Info text here</div>
        </div>
        <div  style="background-color: #b24377">
            <h3>Up to 40% off</h3>
            <p>Text here </p>
            <a href="http://linkhere.com" >Apply Now</a>
        </div>
    </div>
</div>

  • Related