phantom phantom - 5 months ago 8
jQuery Question

prevent effect hover from occurring until previous effect has completed

Currently if I hover over an element it displays the animation I am looking for, and hides the other elements on the page.

The issue I am facing is that if I hover over many of the divs quickly it queues, and hides the divs one after an other. I want to just allow one div to be hidden when hovered on, and when all animations are complete allow the functionality work again.

See jsfiddle here
If you hover quickly over the divs you will see that they appear/disappear and this keeps repeating. I want more control over this, and to only allow the effect to happen again, once the animation is complete.

Please also see code below for convenience.

I tried adding

if(!$(".wrapper").is(":animated")){....


but unfortunately this didn't work.

html

<div class="box-1">
<div class="wrapper">
<div class="background-out label-1 label"></div>
<div class="background-over label-1 label"></div>
<div class="background-info">
<div class="text">Bla bla bla.</div>
</div>
</div>
</div>

<div class="box-2">
<div class="wrapper">
<div class="background-out label-2 label"></div>
<div class="background-over label-2 label"></div>
<div class="background-info">
<div class="text">Bla bla bla</div>
</div>
</div>
</div>


css

.box-1 {
position: absolute;
top: 40%;
left: 40%;
}

.box-2 {
position: absolute;
top: 10%;
left: 40%;
}

.wrapper {
position: relative;
width: 100px;
height: 100px;
margin: 0 0 20px;
}

.background-out,
.background-over {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}

.background-out,
.background-over,
.background-info {
transition: opacity 600ms cubic-bezier(0.55, 0.31, 0.15, 0.93) 0ms, -moz-transform 600ms cubic-bezier(0.55, 0.31, 0.15, 0.93) 0ms, -webkit-transform 600ms cubic-bezier(0.55, 0.31, 0.15, 0.93) 0ms;
}

.background-info {
position: absolute;
left: 100px;
top: 0;
width: 100%;
height: 100%;
opacity: 0.2;
transform-origin: 0% 50% 0px;
transform: rotateY(-90deg);
background-color: #f8f8f8;
}

.background-info .text {
font-size: 12px;
letter-spacing: 1px;
text-align: center;
width: 80%;
margin-left: 10%;
margin-top: 5px;
}

.background-out {
transition-timing-function: linear;
}

.wrapper:hover .background-out {
visibility: hidden;
}

.wrapper:hover .background-over,
.wrapper:hover .background-info {
transform: translate3d(0px, 0px, 0px) rotateY(0deg);
transition: opacity 1000ms cubic-bezier(0.55, 0.31, 0.15, 0.93) 0ms, -moz-transform 1000ms cubic-bezier(0.55, 0.31, 0.15, 0.93) 0ms, -webkit-transform 1000ms cubic-bezier(0.55, 0.31, 0.15, 0.93) 0ms;
opacity: 1;
}

.background-over {
background-color: transparent;
opacity: 0;
transform-origin: 100% 50% 0px;
transform: rotateY(-90deg);
}

.label-1 {
background: yellow;
}

.label-2 {
background: pink;
;
}

.label {
animation-duration: 1s;
animation-name: slidein;
}


JS

$('.wrapper').hover(function() {
$('.wrapper').not(this).fadeOut('slow');
$('.wrapper .label').not(this).removeClass('label');
}, function() {
$('.wrapper').not(this).fadeIn('slow');
});

Answer

You need to use the jQuery .stop() method to prevent the animations queuing.

https://jsfiddle.net/po34gv6v/11/

$('.wrapper').hover(function() {
  $('.wrapper').not(this).stop().fadeOut('slow');
  $('.wrapper .label').not(this).removeClass('label');
}, function() {
  $('.wrapper').not(this).stop().fadeIn('slow');
});

see: https://api.jquery.com/stop/

Comments