Простая анимация наведения 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 анимировался обратно в исходное положение, даже если анимация не завершена при отпускании мыши?
5 ответов
(Без JS!) Вы можете сделать это с помощью CSS3 transition
:
.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
и привязать их к текущему событию.
Попробуй это:
$(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/
jsFiddle Demo
Если вы хотите, чтобы анимация не прерывалась, вы должны позволить jquery управлять ею в fx
очередь. Вы явно говорите это не здесь:
{queue: false}
так что вам нужно изменить это на это:
$(this).animate({marginLeft: '+=50px'}, {queue: true}, 300, 'swing');
и затем он будет ждать, пока анимация не выйдет из очереди, чтобы начать следующую анимацию.
Ссылка: Как узнать с помощью jQuery, анимируется ли элемент?
Вы можете использовать следующий код, чтобы определить, применяется анимация или нет
if( $('.image-photo-previous').is(':animated') ) {...}
Если это так, вы можете использовать функцию обратного вызова в ссылке выше, чтобы подождать (используя setTimeOut
) или рассчитать ожидаемое количество пикселей в пикселях, необходимое для возврата div в исходное положение
Вы можете сбросить 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/
Дайте мне знать, если это то, что вы искали или нет.