49

我有一个下拉菜单。现在,当它向下滑动到多个级别时,我希望它在它消失之前添加大约 2 秒的等待时间,以便用户在.hover()错误地打破它时可以重新进入。

可能吗?

我的幻灯片代码:

$('.icon').hover(function() {
        $('li.icon > ul').slideDown('fast');
    }, function() { 
        $('li.icon > ul').slideUp('fast');
    });
4

9 回答 9

75

这将使第二个函数在执行前等待 2 秒(2000 毫秒):

$('.icon').hover(function() {
    clearTimeout($(this).data('timeout'));
    $('li.icon > ul').slideDown('fast');
}, function() {
    var t = setTimeout(function() {
        $('li.icon > ul').slideUp('fast');
    }, 2000);
    $(this).data('timeout', t);
});

当用户重新悬停以避免疯狂行为时,它还会清除超时。

然而,这并不是一种非常优雅的方式。您可能应该检查一下hoverIntent插件,该插件旨在解决这个特定问题。

于 2009-07-06T21:16:08.183 回答
43

我个人喜欢“hoverIntent”插件:

http://cherne.net/brian/resources/jquery.hoverIntent.html

从页面: hoverIntent 是一个插件,试图确定用户的意图......就像一个水晶球,只有鼠标移动!它的工作方式类似于(并且源自)jQuery 的内置悬停。但是,它不会立即调用 onMouseOver 函数,而是等到用户的鼠标速度足够慢后再进行调用。

为什么?延迟或防止意外触发动画或 ajax 调用。简单的超时适用于小区域,但如果您的目标区域很大,则无论意图如何,它都可能执行。

var config = {    
 sensitivity: 3, // number = sensitivity threshold (must be 1 or higher)    
 interval: 200, // number = milliseconds for onMouseOver polling interval    
 over: makeTall, // function = onMouseOver callback (REQUIRED)    
 timeout: 500, // number = milliseconds delay before onMouseOut    
 out: makeShort // function = onMouseOut callback (REQUIRED)
};
$("#demo3 li").hoverIntent( config ) 

配置选项

灵敏度: 如果鼠标在轮询间隔之间移动的像素数少于此像素数,则将调用“over”函数。最小灵敏度阈值为 1 时,鼠标不得在轮询间隔之间移动。使用更高的灵敏度阈值,您更有可能收到误报。默认灵敏度:7

间隔: hoverIntent 在读取/比较鼠标坐标之间等待的毫秒数。当用户的鼠标第一次进入元素时,它的坐标被记录下来。最快可以调用“over”函数是在单个轮询间隔之后。将轮询间隔设置得更高会增加第一次可能的“过度”调用之前的延迟,但也会增加到下一个比较点的时间。默认间隔:100

结束: 必填。您要调用 onMouseOver 的函数。您的函数接收与 jQuery 的悬停方法相同的“this”和“event”对象。

timeout: 调用“out”函数之前的简单延迟,以毫秒为单位。如果用户在超时到期之前将鼠标移回元素上,则不会调用“out”函数(也不会调用“over”函数)。这主要是为了防止马虎/人类鼠标轨迹暂时(和无意地)使用户离开目标元素......让他们有时间返回。默认超时:0

出: 必填。您要调用 onMouseOut 的函数。您的函数接收与 jQuery 的悬停方法相同的“this”和“event”对象。注意,只有在同一次运行中调用了“over”函数时,hoverIntent 才会调用“out”函数。

于 2009-07-06T21:53:48.967 回答
1

一般的想法是使用setTimeout,如下所示:

$('.icon').hover(function() {
           $('li.icon > ul').slideDown('fast');
    }, function() { 
           setTimeout(function() {
                $('li.icon > ul').slideUp('fast');
           }, 2000);
    });

但是,如果用户将鼠标移出然后再次快速移入鼠标,这可能会产生违反直觉的事情——这并没有考虑到当用户再次将鼠标悬停在它上面时清除超时。这将需要额外的状态。

于 2009-07-06T21:18:22.547 回答
1
$('.icon').on("mouseenter mouseleave","li.icon > ul",function(e){
   var $this = $(this);
   if (e.type === 'mouseenter') {
       clearTimeout( $this.data('timeout') );
       $this.slideDown('fast');
   }else{ // is mouseleave:
       $this.data( 'timeout', setTimeout(function(){
           $this.slideUp('fast');
       },2000) );  
   }
 });
于 2010-08-06T11:19:53.180 回答
1

以下将停止滑动触发 2 秒:

$('.icon').hover(function() {
  $('li.icon > ul').delay(2000).slideDown('fast');
}, function() { 
  $('li.icon > ul').slideUp('fast');
});
于 2011-06-03T08:51:04.143 回答
1

或者你可以简单地使用 transition:all 2s ease-in-out。确保为不同的浏览器添加 -webkit、-moz 和 -o。

于 2013-05-20T07:03:17.353 回答
0

我认为这是您需要的代码:

    jQuery( document ).ready( function($) {  
    var navTimers = [];  
    $('.icon').hover(function() { 
            var id = jQuery.data( this );  
            var $this = $( this );  
            navTimers[id] = setTimeout( function() {  
                $this.children( 'ul' ).slideDown('fast');  
                navTimers[id] = "";  
            }, 300 );  
        },  
        function () {  
            var id = jQuery.data( this );  
            if ( navTimers[id] != "" ) {  
                clearTimeout( navTimers[id] );  
            } else {  
                $( this ).children( "ul" ).slideUp('fast'); 
            }  
        }  
    );  
}); 
于 2013-03-28T08:34:35.533 回答
0
var timer;

var delay = 200;

$('#hoverelement').hover(function() {

    on mouse hover, start a timeout

    timer = setTimeout(function() {

       Do your stuff here 

    }, delay);

}, function() {

   Do mouse leaving function stuff here    

    clearTimeout(timer);
});

//编辑:插入代码

于 2016-03-21T14:53:33.887 回答
0

我想向 Paolo Bergantino 补充一点,您可以在没有数据属性的情况下执行此操作:

var timer;
$('.icon').hover(function() {
    clearTimeout(timer);
    $('li.icon > ul').slideDown('fast');
}, function() {
    timer = setTimeout(function() {
        $('li.icon > ul').slideUp('fast');
    }, 2000);
});
于 2016-02-12T17:14:45.860 回答