djfrsn
djfrsn

Reputation: 301

Avoid mouseover mouseleave conflicts

I'm working with this js fiddle here: http://jsfiddle.net/tPx6x/ The animation works like so

You hover over the text, a circle fades in & begins to pulse 1 second later for as long as your mouse is over the text.

When your mouse pointer leaves the text, the pulse stops after one second and the circle fades out.

The issue arises when you do this:

Put your mouse over the text, remove the pointer from the text, THEN place the pointer back over the text before the script has a chance to finish(1-1.4s).

You won't be able to make the circle appear properly agin...you will have to allow the script to reset. That is the problem.

What is the best way to tackle this issue?

Example code:

 <div class='circle__title_project-management'>
 <h1>project management</h1>
 </div>
 <div class='circle__project-management hidden'></div>



.circle__project-management, .circle__title_project-management
{
    display: inline-block;
    cursor: pointer;
}

.circle__project-management
{   
    margin-left: 8px;
    vertical-align: -4.07px;
    background-color: transparent;
    border: 2px solid #00DBFF;
    width: 30px;
    height: 30px;
    border-radius: 90px;
    top: 280px;
    left: 40px;
}

.hidden
{
    visibility: hidden;
}

.visible
{
    visibility: visible;
}

.animate-infinite 
{
    animation-iteration-count: infinite;
    -moz-animation-iteration-count: infinite;
    -webkit-animation-iteration-count: infinite;
}



    var circleTitle =  $('.circle__title_project-management h1');
var circle = $('.circle__project-management');
var initTimeout = 1000;
var initTimeoutPlus = 1400;
circleTitle.mouseover( function() {
    circle.removeClass('hidden');
    circle.addClass('animated fadeIn');   
    setTimeout( function() {
        circle.addClass('pulse animate-infinite');
        circle.removeClass('fadeIn');
    }, initTimeout);
});
circleTitle.mouseleave( function() {
    setTimeout( function() {
        circle.stop().removeClass('pulse animate-infinite visibility');
        circle.addClass('fadeOut');
    }, initTimeout);
    setTimeout( function() {
        circle.removeClass('fadeOut');
        circle.addClass('hidden');
    }, 1400);
});

Upvotes: 1

Views: 448

Answers (4)

blgt
blgt

Reputation: 8205

You should note that setTimeout has a return value. You want to clear previous timeouts before you start new ones; otherwise you can get a timeout queue which completely skews your animations. Something like this:

var myTimeout;
...
clearTimeout(myTimeout);    
myTimeout = setTimeout(...);

Not sure if this is exactly what you were going for, but along these lines: http://jsfiddle.net/FYY38/

More info here: http://www.w3schools.com/js/js_timing.asp


Also, it looks like the circle.stop() call is doing nothing (as it's css-animated)

Upvotes: 1

Ayyash
Ayyash

Reputation: 4399

Probably if you just add a key on mouseover, and toggle it after mouseleave, and before you trigger any mouseleave timeout events, check the key, if it is set, ignore, else go ahead and execute mouseleave

this way if the key is "on" it means a mouse over occurred, if it was off, it means the mouseleave occurred and it is still occurring

    var key = false;
circleTitle.mouseover( function() {
    key = true;
    circle.removeClass('hidden');
    circle.addClass('animated fadeIn');   
    setTimeout( function() {
        circle.addClass('pulse animate-infinite');
        circle.removeClass('fadeIn');
    }, initTimeout);
});
circleTitle.mouseleave( function() {
    key = false;
    setTimeout( function() {
        if (!key){
            circle.stop().removeClass('pulse animate-infinite visibility');
            circle.addClass('fadeOut');
        }
    }, initTimeout);
    setTimeout( function() {
        if (!key){
            circle.removeClass('fadeOut');
            circle.addClass('hidden');
        }
    }, 1400);
});

Upvotes: 0

Farshad
Farshad

Reputation: 1485

you can set time out to mouse over function to cover the time delay for mouseleave.

note that the first run must be without delay

var initTimeout = 1000;
var initTimeoutPlus = 1400;
var firstrun = true;
circleTitle.mouseover( function() {

    if (firstrun) {
        initTimeoutPlus = 0;
        firstrun = false;
    } else initTimeoutPlus = 1400; 

     setTimeout(function() {
         circle.removeClass('hidden');
        circle.addClass('animated fadeIn');   
        setTimeout( function() {
            circle.addClass('pulse animate-infinite');
            circle.removeClass('fadeIn');
        }, initTimeout);
     }, initTimeoutPlus);
});

Upvotes: 0

user1835565
user1835565

Reputation: 141

To avoid antagonist behaviours, maybe add a class to your element to tag it when the event is triggered and remove it when another is triggered. That way you can stay in control of what's going on.

Upvotes: 0

Related Questions