3

I'm using animate() to animate the DIV tag to the left when the pointer is over the DIV. And when the pointer leaves the DIV tag it animates back to it's original position. The problem here is that the animation moves the DIV tag 50 pixels to the left on mouse over and 50 pixels to the right on mouse leave.

This makes the DIV to move 50 pixels to the right even if the animation is not completed.

$('body').on('mouseenter', '.image-photo-previous', function() {
    $(this).animate({marginLeft: '-=50px'}, 300, 'swing');
});

$('body').on('mouseleave', '.image-photo-previous', function() {
    $(this).animate({marginLeft: '+=50px'}, {queue: false}, 300, 'swing');
});

http://jsfiddle.net/edgren/CubZy/

How can I make the DIV tag to animate back to its original position even if the animation is not complete on mouse leave?

Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
Airikr
  • 6,258
  • 15
  • 59
  • 110

5 Answers5

4

(Without JS!) You can do it using CSS3 transition:

DEMO (CSS only)

.image-photo-previous {
    background-color: #222222;
    height: 100px;
    width: 200px;
    transition: 0.3s;         /* Transition! */
}
.image-photo-previous:hover{
    margin-left: -50px;
}

Using jQuery:

LIVE DEMO

$(".image-photo-previous").on('mouseenter mouseleave', function( e ) {
    $(this).stop().animate({marginLeft: e.type=="mouseenter"?-50:0}, 300);
});

The .stop() method will prevent some ugly animations buildups, and with a bit of Ternary Operator (?:) you're on the right way.

Your example does not suit your needs cause at any new event you were messing with some new added margin calculations (to un-ended animations) due to += and -= that were added to the current DIV style, resulting in incorrect element positions specially on fast mousemovements. stop() clears that behavior and all you need is to strictly define the positions: -50 and 0 and bound them to the current event.

Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
2

Try this:

$(document).ready(function() {

    $('body').on('mouseenter', '.image-photo-previous', function() {
        $(this).stop(true,true).animate({marginLeft: '-=50px'}, 300, 'swing');
    });

    $('body').on('mouseleave', '.image-photo-previous', function() {
        $(this).stop(true,true).animate({marginLeft: '+=50px'}, {queue: false}, 300, 'swing');
    });

});

Read more about .stop(): http://api.jquery.com/stop/

Dan-Nolan
  • 6,594
  • 4
  • 27
  • 32
0

jsFiddle Demo

If you want the animation to not be interrupted then you must let jquery manage it in its fx queue. You explicitly tell it not to here:

{queue: false}

so you need to change that to this:

$(this).animate({marginLeft: '+=50px'}, {queue: true}, 300, 'swing');

and then it will wait until the animation leaves the queue to start the next animation.

Travis J
  • 81,153
  • 41
  • 202
  • 273
  • -1 because the OP asked "How can I make the DIV tag to animate back to its original position even if the animation is not complete on mouse leave?" – Kenneth Apr 21 '13 at 22:43
  • @Kenneth - He never stated it should not complete, only that when it is not complete it fails to return to its starting place. – Travis J Apr 21 '13 at 22:44
  • True, I undid the -1. Let OP decide if that's what he wants. Apologies! – Kenneth Apr 21 '13 at 22:45
0

You can reset marginLeft to its original value or '' if there was no original value.

Also, call $(this).stop(); in your mouseleave to cancel the previous animation.

$(document).ready(function() {
    $('body').on('mouseenter', '.image-photo-previous', function() {
        startMargin = $(this).css('marginLeft');
        $(this).animate({marginLeft: '-=50px'}, 300, 'swing');
    });

    $('body').on('mouseleave', '.image-photo-previous', function() {
        $(this).stop();
        $(this).animate({marginLeft: ''}, {queue: false}, 300, 'swing');
    });
});

fiddle: http://jsfiddle.net/ExUzJ/2/

Let me know if that is what you were looking for or not.

Matt Wonlaw
  • 12,146
  • 5
  • 42
  • 44
0

Reference: How do I find out with jQuery if an element is being animated?

you can use the following code to determine whether an animation is being applied or not

if( $('.image-photo-previous').is(':animated') ) {...}

If so, you can use the callback function in the link above to wait (using setTimeOut) or calculate the expected margin pixels required to get the div back to its original postion

Community
  • 1
  • 1