Простая анимация при наведении DIV

Я использую animate() для анимации тега DIV слева, когда указатель находится над DIV. И когда указатель покидает тег DIV, он возвращается в исходное положение. Проблема здесь в том, что анимация перемещает тег DIV на 50 пикселей влево при наведении мыши и на 50 пикселей вправо при отпускании мыши.

Это заставляет DIV перемещаться на 50 пикселей вправо, даже если анимация не завершена.

$('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/

Как я могу заставить тег DIV анимироваться обратно в исходное положение, даже если анимация не завершена при отпускании мыши?


person Airikr    schedule 21.04.2013    source источник


Ответы (5)


(Без JS!) Вы можете сделать это с помощью CSS3 transition:

ДЕМО (только CSS)

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

Использование jQuery:

РЕАЛЬНАЯ ДЕМО

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

Метод .stop() предотвратит создание некоторых уродливых анимаций, а с небольшим количеством Ternary Operator (?:) вы на правильном пути.

Ваш пример не соответствует вашим потребностям, потому что в любом новом событии вы возились с некоторыми новыми расчетами добавленных полей (для незавершенных анимаций) из-за += и -=, которые были добавлены в текущий стиль DIV, что привело к неправильным позициям элементов, особенно на быстром движения мыши. stop() устраняет это поведение, и все, что вам нужно, это строго определить позиции: -50 и 0 и привязать их к текущему событию.

person Roko C. Buljan    schedule 21.04.2013
comment
Ну это просто еще лучше! O.o Большое спасибо :D Я приму это, когда смогу - person Airikr; 22.04.2013

Попробуй это:

$(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');
    });

});

Подробнее о .stop(): http://api.jquery.com/stop/

person Dan-Nolan    schedule 21.04.2013

jsFiddle Demo

Если вы хотите, чтобы анимация не прерывалась, вы должны позволить jquery управлять ею в своей очереди fx. Вы явно говорите, что здесь нет:

{queue: false}

поэтому вам нужно изменить это на это:

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

а затем он будет ждать, пока анимация не покинет очередь, чтобы запустить следующую анимацию.

person Travis J    schedule 21.04.2013
comment
-1, потому что OP спросил, как я могу заставить тег DIV анимироваться обратно в исходное положение, даже если анимация не завершена при отпускании мыши? - person Kenneth; 22.04.2013
comment
@Kenneth - он никогда не говорил, что он не должен завершаться, только то, что, когда он не завершен, он не может вернуться в исходное место. - person Travis J; 22.04.2013
comment
Правда, я отменил -1. Пусть ОП решит, хочет ли он этого. Извинения! - person Kenneth; 22.04.2013

Вы можете сбросить marginLeft до исходного значения или '', если исходного значения не было.

Кроме того, вызовите $(this).stop(); в своем mouseleave, чтобы отменить предыдущую анимацию.

$(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');
    });
});

скрипка: http://jsfiddle.net/ExUzJ/2/

Дайте мне знать, если это то, что вы искали или нет.

person Matt Crinklaw-Vogt    schedule 21.04.2013

Ссылка: Как мне найти с jQuery, если элемент анимируется?

вы можете использовать следующий код, чтобы определить, применяется ли анимация или нет

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

Если это так, вы можете использовать функцию обратного вызова в приведенной выше ссылке, чтобы подождать (используя setTimeOut) или вычислить ожидаемые пиксели поля, необходимые для возврата div в исходное положение.

person Muhammad Omar ElShourbagy    schedule 21.04.2013