【问题标题】:How to tell .hover() to wait?如何告诉 .hover() 等待?
【发布时间】:2010-11-08 12:32:42
【问题描述】:

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

有可能吗?

我的幻灯片代码:

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

【问题讨论】:

    标签: javascript jquery time hover settimeout


    【解决方案1】:

    这将使第二个函数在执行前等待 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 插件,该插件旨在解决此特定问题。

    【讨论】:

    • 这应该是第一个答案。
    • 嗨。我在this jsFiddle 中为slideDown()slideUp() 尝试相同的方法,但slideUp() 效果不佳。你能告诉我我在这里错过了什么吗?注意:我正在尝试不使用hoverIntent() 函数。
    • @him056 您的 jsFiddle 存在范围问题。它在这里工作jsfiddle.net/671noauq
    • jquery 插件在打字稿中表现不佳,所以这就是我的方式。
    【解决方案2】:

    我个人喜欢“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”对象。

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

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

    【讨论】:

    • 我用了很多年,直到我意识到它对于像这个问题这样的情况来说是一个矫枉过正。此线程中的手动代码示例运行良好。
    【解决方案3】:

    总体思路是使用setTimeout,像这样:

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

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

      • 我认为这基本上实现了相反的效果:悬停动作不会立即触发,但必须悬停至少 2 秒才能发生任何事情。仍然有用,但不完全是问题的答案。我错了吗?
      【解决方案5】:
      $('.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) );  
         }
       });
      

      【讨论】:

        【解决方案6】:

        或者你可以简单地使用 过渡:所有 2s 缓进出。 确保为不同的浏览器添加 -webkit、-moz 和 -o。

        【讨论】:

          【解决方案7】:

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

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

          【讨论】:

            【解决方案8】:
            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);
            });
            

            //编辑:插入代码

            【讨论】:

              【解决方案9】:

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

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2020-07-29
                • 2022-01-02
                • 1970-01-01
                • 2017-12-06
                • 2021-02-17
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多