【问题标题】:Problem with jQuery hover functionjQuery悬停功能的问题
【发布时间】:2011-06-30 22:02:57
【问题描述】:
$('#element').children('ul').children('li').children('a').hover(function(){     
    var _this = $(this);
    _this.siblings('div').show();
},function(){
    _this.siblings('div').hide();
})

它按原样工作,显示 div。但它不会隐藏它之后。我猜 _this 没有在 callbacl 函数中定义。我如何在该函数中传递它而不必从 DOM 中再次选择它?我认为这是一个非常基本的 javascript 问题,我只是想不通。

【问题讨论】:

    标签: jquery


    【解决方案1】:

    这两个函数都需要这个:

    var _this = $(this);
    

    但是更好的方法是这样的:

    $('#element > ul > li > a').hover(function(e){ 
        $(this).siblings('div').toggle( e.type === 'mouseenter' );
    });
    

    ...或者,如果您希望避免多次调用 .siblings(),您可以这样做:

    $('#element > ul > li > a').each(function() {
        var $th = $(this);
        var sibs = $th.siblings('div');
        $th.hover(function(e){ 
            sibs.toggle( e.type === 'mouseenter' );
        });
    });
    

    仅供参考:当您执行$(this) 时,您不会从 DOM 中选择任何内容。 this 只是对调用处理程序时为您设置的元素的直接引用。

    【讨论】:

    • 第二种方法看起来很有趣。有好处吗?似乎它缓存了所有兄弟姐妹,所以它不必在每次悬停时查看 DOM,对吧?
    • @Marcel:没错。好处是选择被缓存。不利的一面是,就创建的处理函数的数量而言,开销更大,当然还有被缓存的元素。如果你有很多没有太多<a> 元素的兄弟姐妹,那就没问题了。如果你有很多 <a> 元素,并且没有太多兄弟姐妹,我会使用第一个解决方案。
    【解决方案2】:

    在您的示例中,您将两个函数作为参数传递给 .hover() 方法,因此您在函数内声明的任何变量仅在该函数的 范围 内可用。所以如果需要在第二个函数中使用_this变量,则需要再次声明。

    但在您的情况下,中间变量应该不是必需的,您可以完全省略它:

    $('#element').children('ul').children('li').children('a').hover(function(){ 
        $(this).siblings('div').show();
    } ,function(){
        $(this).siblings('div').hide();
    })
    

    【讨论】:

    • 只是指出这一点,但如果你声明一个变量而不使用var,你应该能够使用window.variablename再次调用它——在这种情况下是window._this
    • @Zydeco,虽然在技术上是正确的,但我不会向我最大的敌人推荐它。实际上,您会将全局范围赋予名为_this 的变量,该变量在悬停处理程序之外没有上下文意义。呃。
    • 我什至不会使用 _this,但是说你在函数中声明的任何变量都只保留在该函数中,无法使用它外面,是不真实的。
    • 在语义上准确地说,这是一个变量声明var x;,这是一个赋值x = 1。现在在 JavaScript 中,您可以分配一个以前未声明的变量,它会自动接收全局范围。但是,在函数内声明的变量总是私有作用域的说法是不真实的,实际上是不真实的:)
    • 我不知道我们在争论语义,或者根本不想要精确,因为对于只想知道什么功能有效的人来说,这通常是一个失败的原因,但我相信我会说话当我说谢谢时,所有关心它的人。包括我自己,也就是说,因为我对这种事情的了解显然比你少。 :)
    【解决方案3】:

    为什么不使用 mouseenter 和 mouseleave?

    或许:

    $('#element').children('ul').children('li').children('a').hover(function(){ 
    
        var _this = $(this);
        _this.siblings('div').show();
    
    },function(){
    
        var _this = $(this);
        _this.siblings('div').hide();
    })
    

    如果我在第一个函数语句中没有记错的话,_this 是“私有的”...

    【讨论】:

    • 我不知道“悬停”是如何工作的,但如果它使用鼠标悬停,那么每次鼠标移到元素上时都会调用它。
    • 其实..刚刚检查。这与使用 mouseenter 和 mouseleave 相同。所以坚持你的函数,但记得在两个函数中声明 _this。
    【解决方案4】:

    如果#element 中的所有链接都在li 中,则可以使用$('#element > a').hover() 调用它们。

    试试这个:

    $('#element > a').mouseover(function () { $(this).siblings('div').show(); }).mouseout(function () { $(this).siblings('div').hide(); });

    【讨论】:

    • 我这样做只是出于性能原因。 stackoverflow.com/questions/3177763/…
    • 可以理解,但为了代码的清晰性,我必须坚持使用$('#element > a'),因为使用现在的代码所获得的性能提升似乎最多可以忽略不计。当然,除非你有这么多 div 来调用它,否则它实际上会显着减慢它。但是你还有其他问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-05
    • 1970-01-01
    • 2014-01-18
    相关资源
    最近更新 更多