jQuery, если мышь остановлена на 2 секунды. начать анимацию или вообще не анимировать

#jquery #animation

#jquery #Анимация

Вопрос:

Это ситуация: у меня есть список продуктов с 4 продуктами подряд. При наведении курсора мыши на один из продуктов отображается всплывающая подсказка. Меня беспокоит то, что если вы быстро перемещаете мышь слева направо или что-то еще по продуктам, вы получите все всплывающие подсказки, отображаемые в течение нескольких секунд. Интересно, могу ли я сказать jQuery, чтобы он запускал анимацию, только если мышь находится над продуктом в течение 2 секунд. Итак, если вы наведете курсор мыши на продукт на 1 сек., а затем уберете мышь, анимация вообще не начнется. Я использую jQuery 1.2.6, и это мой код для всплывающих подсказок:

 $(document).ready(function(){
$('.thumb-image').hover(function() {
    $(".thumb-image").mousemove(function(e){
        $(this).find(".t-desc").filter(":not(:animated)").fadeIn(500);
            $(this).find(".t-desc").css({
                top: (e.pageY   27)   "px",
                left: (e.pageX - 20)   "px"     });
    }); 
    }, function() {
        $(this).find(".t-desc", this).fadeOut(250);             
}); 
});
 

Ответ №1:

Это, мой друг, то, что вам нужно: плагин jQuery hoverIntent

Ответ №2:

Установите таймер при наведении курсора и показывайте подсказку только в том случае, если наведение длится дольше этого времени. Если вы оставляете текущий объект до срабатывания таймера, вы отменяете ожидающий таймер. Если вы оставите текущий объект после отображения подсказки, он исчезнет.

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

Вы можете сделать это следующим образом:

 $(document).ready(function(){
    var tipTimer = null;
    $('.thumb-image').hover(function() {
        var self = this;
        if (tipTimer) {
            clearTimeout(tipTimer);
            tipTimer = null;
        }
        tipTimer = setTimeout(function() {
            tipTimer = null;
            $(self).find(".t-desc").filter(":not(:animated)").stop(true, true).fadeIn(500);
                $(self).find(".t-desc").css({
                    top: (e.pageY   27)   "px",
                    left: (e.pageX - 20)   "px"});
            }, 2000);
        }, function() {
            if (tipTimer) {
                clearTimeout(tipTimer);
                tipTimer = null;
            }
            $(this).find(".t-desc", this).stop(true, true).fadeOut(250);             
    }); 
});
 

Комментарии:

1. Концепция надежна. Где-то может быть синтаксическая ошибка, но без рабочего примера кода нам трудно с этим помочь. Когда вы говорите «не работает», что вы видите? Есть ли ошибки JS в консоли ошибок? Появляется ли оно через 2 секунды? Что происходит?

2. ХОРОШО, на данный момент проблема заключается в использовании (this) $(this) . find … fadeIn(500); $(this).find(«.t-desc»).css({ если я заменю $ (this) на $ (‘.thumb-image’) скрипт работает, но единственная проблема в том, что через 2 секунды он показывает всевсплывающие подсказки продуктов, потому что у меня больше нет оператора $ (this), я думаю.

3. вы пробовали плагин jquery hover intent

4. Я изменил его, чтобы устранить проблему, this которая недопустима внутри обратного вызова таймера.

5. Теперь это работает, единственное, что осталось, это то, что функция «.mousemove» отсутствует в коде, который вы мне дали. Таким образом, всплывающая подсказка не следует за мышью.

Ответ №3:

Вы должны использовать mouseenter и mouseleave .

В mouseenter запустите setTimeout, задерживая анимацию на 2 секунды. При mouseleave сбросьте время ожидания.

Поэтому, если мышь наведена менее чем на 2 секунды, ничего не будет отображаться.

Пожалуйста, спросите, нужен ли вам практический пример.

Редактировать: Итак, я бы попробовал это :

 $(document).ready(function(){

    var timer;
    $('.thumb-image').bind('mouseenter',enter).bind('mouseleave',leave);

    function enter(){
        var $this = $(this);
        clearTimeout(timer);
        timer = setTimeout(function()
        {
                $this.find(".t-desc").filter(":not(:animated)").fadeIn(500);
                $this.find(".t-desc").css({
                    top: (e.pageY   27)   "px",
                    left: (e.pageX - 20)   "px"     });
            },2000);
    }); 

    function leave() {
        var $this = $(this);
        clearTimeout(timer);
        $this.find(".t-desc", this).fadeOut(250);             
    }); 

});
 

… но я не могу быть уверен, что это сработает, не глядя на ваш код.

Комментарии:

1. Да, я буду очень благодарен, если вы не сможете показать мне, как это написать. Заранее благодарю вас.

Ответ №4:

Хорошо, мой друг помог мне в этом, и вот окончательный код, который работает отлично:

 $(document).ready(function(){
var tipTimer = null;
$(".thumb-image").mouseover(function(){
    var self = this;
    $(self).bind('mousemove', function(e){                
        $(self).find(".t-desc").css({
            top: (e.pageY   27)   "px",
            left: (e.pageX - 20)   "px"
        }); 
    });
    if (tipTimer) {
        clearTimeout(tipTimer);
        tipTimer = null;
    }
    tipTimer = setTimeout(function() {
        tipTimer = null;
        $(self).find(".t-desc").filter(":not(:animated)").stop(true, true).fadeIn(500);
        }, 600);      

}).mouseout(function(){
        $(this).unbind('mousemove');
        if (tipTimer) {
            clearTimeout(tipTimer);
            tipTimer = null;
        }
        $(this).find(".t-desc", this).stop(true, true).fadeOut(250);
});
 

});