添加setTimeout到现有的jQuery脚本的语法问题

3
我想在以下代码中添加setTimeout,以便在淡出效果执行之前有一个短暂的暂停。
$(document).ready(function() {  
    $('#menu li').hover(
        function() {
            $('ul', this).slideDown(50);
        }, 
        function() {
            $('ul', this).fadeOut(100);
        }
    );
});

我正在尝试这个,但是猜测语法可能有误:

$(document).ready(function() {  
    $('#menu li').hover(
        function() {
            $('ul', this).slideDown(50);
        },
        function() {
            setTimeout(function() {
                $('ul,' this).fadeOut(100);
            });
        }
    );
});

抱歉如果这个问题很愚蠢。我是一个jQuery的初学者。

2个回答

3

thissetTimeout()中有不同的含义。您需要引用变量中所需的this或先获取ul并引用它。

var th = this;
setTimeout(function() {
    $('ul', th).fadeOut(100);
});

或者

var $ul = $('ul',this);
setTimeout(function() {
    $ul.fadeOut(100);
});

+1 - 这个很好,$.proxy()也是一个保持上下文的替代方法。 - Nick Craver
@Nick - 谢谢。我为什么总是忘记 $.proxy() ?! - user113716

1
你可能需要在使用clearTimeout()时清除超时(以防快速悬停/移开),可以尝试类似以下的代码:
$(function() {  
  $('#menu li').hover(function() {
    clearTimeout($.data(this, 'timer'));
    $('ul', this).slideDown(50);
  }, function() {
    $.data(this, 'timer', setTimeout($.proxy(function() {
      $('ul,' this).fadeOut(100);
    }, this), 400));
  });
});

使用$.data()存储/检索计时器ID,当前延迟为400毫秒,只需相应地进行调整。


有没有“this”的相反?当您的幻灯片向下滑动时,是否有一种方法可以淡出所有其他ul? - Tom
@Tom - 你可以使用 .not(),例如:$('#menu li').not(this).find('ul') 来获取所有其他子级 <ul> 元素。 - Nick Craver
谢谢,Nick。我不得不添加一些类来区分不同级别的ul和li,但这对我很有用。再次感谢! - Tom
@Tom - 欢迎 :) 如果有帮助的话,你也可以使用$(this).children('ul')来进一步深入一级,而不是使用$('ul', this) - Nick Craver
为了澄清,我不得不添加识别类以防止第二级ul过早消失。否则,它们会在我从顶级li上移开鼠标时立即消失。$(this).children('ul')似乎无法解决这个问题,除非我做错了:$(document).ready(function(){ $('#menu li').hover(function() { clearTimeout($.data(this, 'timer')); $(this).children('ul').slideDown(50); $('#menu li').not(this).children('ul').hide(); }, function() { $.data(this, 'timer', setTimeout($.proxy(function() { $(this).children('ul').fadeOut(100); }, this), 500)); }); }); - Tom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接