将$(this)传递给一个函数。

7

我正在尝试构建一个媒体播放列表,可以在结束信用、播放视频和缩略图悬停时更改标题,并在下一个/上一个点击时。因此,我需要编写一些函数,然后可以一起调用。就像这样:

    function showBox()
    {
        $(this).parents('.container').find('.box').show();
    };
    
    function hideBox()
    {
        $(this).parents('.container').find('.box').hide();
    };
    
    $('a').hover(
        function()
        {
            showBox();
        },
        function()
        {
            hideBox();
        }
    );

问题在于$(this)不能从.hover函数传递到其他函数中。我该怎么做?
6个回答

7
根据 @patrickdw 的回答,jQuery 将事件回调的作用域设置为触发事件的 DOM 元素。例如,可以在 click() 处理程序的文档中查看 eventObject 参数。
我的原始回答(下面)适用于创建 jQuery 插件时,以便您可以在执行期间调用自己的自定义方法并将 jQuery 对象设置为 this。但是,这不是原始问题的正确和简单答案。
// Within a plug-in, `this` is already a jQuery object, not DOM reference
$.fn.showBox = function(){ this.parents('.container').find('.box').show(); };
$.fn.hideBox = function(){ this.parents('.container').find('.box').hide(); };
$('a').hover(
  function(){ $(this).showBox() },
  function(){ $(this).hideBox() }
);

编辑: 或者,如果您想要将一个名称添加到全局jQuery方法命名空间中:

$.fn.myBox = function(cmd){
  this.closest('.container').find('.box')[cmd]();
};

$('a').hover(
  function(){ $(this).myBox('show') },
  function(){ $(this).myBox('hide') }
);

更普遍地说:
$.fn.myBox = function(cmd){
  switch(cmd){
    case 'foo':
      ...
    break;
    case 'bar':
      ...
    break;
  }
  return this;
};

更多信息请参阅jQuery插件编写指南


+1 - 这是另一种不需要闭包的绝佳方法。好答案。 - g.d.d.c
1
优雅的jQuery方式。但是需要注意的是,插件的指南通常要求单个命名空间入侵。因此,.theBox('open') / .theBox('close') 更符合规范。 - Orbling
1
非常好的观点,@Orbling。我认为当将自己的代码封装成插件时,这个指南是完全合理的,但对于独立脚本中的一次性使用可能是可以违反的。我已经更新了我的答案,展示了一种实现方式。 - Phrogz
@Phrogz:是的,我非常同意。由于这个问题看起来可能是一个更大的努力的一部分,所以我想把它放进去。 - Orbling
这太棒了,伙计们。我将要编写很多函数(例如nextCredit、prevCredit、nextTitle、prevTitle),那么我该如何处理命名空间呢? - Drew Baker
@DrewBaker,我可能会使用switch(cmd){...}来处理各种不同的命令,而不是上面展示的可爱的小技巧。 - Phrogz

3

如果您只是这样做:this将保留下来。

$('a').hover(showBox,hideBox);

编辑:为回答评论中的问题,此方法适用于您分配为事件处理程序的任何函数。无论是匿名函数还是具有名称的函数都可以。

代码如下:

$('a').click(function() { 
    alert( this.tagName ); 
});

...与以下内容相同:

function alertMe() {
    alert( this.tagName );
}

$('a').click( alertMe );

请提供需要翻译的具体内容。
function alertMe() {
    alert( this.tagName );
}

$('a').bind('click', alertMe );

1
@Drew:没有任何缺点。这是最简单的方法。@Šime Vidas的解决方案实际上是相同的,只是他用匿名函数替换了你的命名函数。我认为你想给它们命名有原因。坦率地说,我认为使用命名函数代替匿名函数是一个好主意。增加清晰度。不确定为什么没有建议这样做。另一个用户提供的插件示例似乎只会增加复杂性和开销,而没有任何真正的好处。传递某种形式的“this”作为参数的解决方案也会增加开销但没有好处。 - user113716
+1 我感到震惊和失望,我没有意识到这是事实。 - Phrogz
@Phrogz:我必须说,当我到达时,我有点惊讶你和@Šime还没有提供这个解决方案。所以我很高兴将其加入其中。;o) - user113716
1
@DrewBaker 请接受patrickdw的答案作为正确答案;我不确定是否删除我的回答,因为它有助于了解插件和扩展jQuery对象的能力。然而,这个答案显然是正确的。我将编辑我的答案来说明这一点。 - Phrogz
1
@DrewBaker 哎呀,我太蠢了。 $('a').click(function(){ doThis.call(this); andThis.call(this); }); 或者如果你需要事件对象: $('a').click(function(e){ doThis.call(this,e); andThis.call(this,e); }); - Phrogz
显示剩余8条评论

3
在Javascript中,你可以使用call()apply()来执行一个函数并明确指定this
$('a').hover(
    function()
    {
        showBox.call(this);
    },
    function()
    {
        hideBox.call(this);
    }
);
< p > call() 的第一个参数指定函数中 this 关键字所引用的对象。其他参数将作为函数调用中的参数使用。


2

您需要将代码修改为如下内容:

function showBox(elem)
{
    elem.parents('.container').find('.box').show();
};

function hideBox(elem)
{
    elem.parents('.container').find('.box').hide();
};

$('a').hover(
    function()
    {
        var $this = $(this);

        showBox($this);
    },
    function()
    {
        var $this = $(this);

        hideBox($this);
    }
);

这样不行。hover(hoverOverFn, hoverOffFn) -- 或许将绑定移到外面,但我不太清楚问题在问什么 :-) - user166390
@pst - 在重新阅读后捕捉到了它,更新以正确设置变量。 - g.d.d.c
@gddc 现在不需要缓存了,直接使用 showBox($(this)); 如何? - Phrogz

2
$('a').hover(function() {
    $(this).closest('.container').find('.box').show();
}, function()  {
    $(this).closest('.container').find('.box').hide();
});

1
showBoxhideBox 中添加参数,以便它们可以接受元素,然后调用 showBox($(this))hideBox($(this))

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