Отменить все анимации jQuery slideUp и slideDown в очереди

У меня есть интерфейс, который активно использует эффекты jQuery slideUp и slideDown для расширения элементов в виде трех состояний.

onmouseover: function() { 
this.find('.details', this).slideDown(); 
},
onmouseout: function() { 
this.find('.details', this).slideUp(); 
}

Однако, когда пользователь быстро перемещает мышь по этим элементам интерфейса, анимация не успевает за ними, и элементы будут скользить вверх и вниз еще долго после того, как мышь покинет область интерфейса.

Есть ли способ отменить все анимации слайдов в очереди, когда мышь покидает контейнер div элемента?


person Candidasa    schedule 02.03.2010    source источник


Ответы (7)


Я считаю, что вы должны просто добавить .stop(), и он позаботится об этом за вас:

onmouseover: function() { 
this.find('.details', this).stop().slideDown(); 
},
onmouseout: function() { 
this.find('.details', this).stop().slideUp(); 
}
person Matt Crest    schedule 02.03.2010
comment
Также убедитесь, что вы используете jQuery 1.7.2 или более позднюю версию, так как ранее была ошибка при использовании slideUp() и slideDown() с stop(), где, если вы быстро навели и выключили пару раз, ваш элемент страдают от странных проблем с ростом. - person jackocnr; 12.05.2012
comment
Я наблюдаю эти странные проблемы даже с jQuery 1.7.2... вы уверены в номере версии? - person Joachim Breitner; 17.09.2012
comment
Я получаю те же проблемы в 1.9. Ключ в том, чтобы удалить .stop() из slideDown(). Если он есть, jQuery иногда просто прыгает прямо на заданную высоту, останавливая анимацию. - person jclancy; 02.08.2013
comment
У меня была такая же проблема с jquery-1.8.3 либо с использованием clearQueue(), либо stop()... Наконец-то я использовал .stop(true, true)! - person Stphane; 01.10.2013

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

$("...").hover(function() {
  $(this).stop(true, true).slideDown();
}, function() {
  $(this).stop(true, true).slideUp();
});

Вам нужны true в остановке, потому что они очищают очереди ожидающих анимации. Если вы их не используете, вы обнаружите, что быстрое и многократное перемещение мыши по элементу приведет к ошибочным результатам.

person Andrew Bullock    schedule 21.07.2011

Вообще говоря, вы хотите вызвать stop() при запуске такой анимации:

$("...").hover(function() {
  $(this).stop().slideDown();
}, function() {
  $(this).stop().slideUp();
});

Этого должно быть достаточно, чтобы избежать длительных очередей анимации.

Вы также можете использовать $.clearQueue() для глобального удаления анимаций, которые еще не начались.

Кроме того, если вы устанавливаете их для mouseover() и mouseout(), возможно, будет понятнее просто использовать событие hover(). вместо.

person cletus    schedule 02.03.2010

Также гораздо лучше, если вы поместите параметры в stop(), вот так: stop(true,true)...

person user403151    schedule 27.07.2010

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

Поэтому я пришел с решением, которое не связано с отменой очередей, но может помочь некоторым из вас. Решение состоит в том, чтобы сдвинуть его вниз или вверх, когда цель анимации в данный момент не анимируется.

$("#trigger").on({
    mouseover: function() {
        $("#animationTarget").not(":animated").slideDown();
    },
    mouseleave: function() {
        $("#animationTarget").not(":animated").slideUp();
    }
});
person falsarella    schedule 09.04.2014

Вы можете сделать что-то вроде следующего: http://jsfiddle.net/3o2bsxo6/3/

JavaScript

$('h5').each(function(){
    $(this).unbind('mouseover'); //unbind previous events (prevent repeats)
    $(this).unbind('mouseout');

    $(this).on('mouseover',function(){
        if(!$(this).next('.details').is(':visible')){ //if not visible
             $(this).next('.details').slideDown();   //slidedown                        
        }
    })  
    $(this).on('mouseout',function(){
        if($(this).next('.details').is(':visible')){ //if visible
             $(this).next('.details').slideUp();    //slideup                           
        }
    })      
})

html:

<h5>Hover To Slide</h5>
<p class="details">
However, when the user quickly moves the mouse over these interface elements the animations can't keep up and the items will be sliding up and down long after the mouse has left the interface area.    
</p>
<h5>Hover To Slide</h5>
<p class="details">
However, when the user quickly moves the mouse over these interface elements the animations can't keep up and the items will be sliding up and down long after the mouse has left the interface area.    
</p>
<h5>Hover To Slide</h5>
<p>
However, when the user quickly moves the mouse over these interface elements the animations can't keep up and the items will be sliding up and down long after the mouse has left the interface area.    
</p>

CSS:

p{
    display:none;
}
person maudulus    schedule 17.04.2015

Аналогичный запрос был опубликован в этой ветке. Используя

stop(true, false)
, вы можете добиться эффекта без ошибок.

$('#YourDiv').on('mouseenter', function(){
   $(this).next().slideDown(250).stop(true, false).slideDown()  
});

Я предположил, что после #YourDiv есть элемент, для которого вы хотите добавить анимацию слайдов вверх и вниз.

Это перейдет к анимации последнего события и очистит все ожидающие события в цепочке.

person Debadatta Meher    schedule 14.11.2015