将函数作为变量传递给jQuery .click()

4
我正在使用一个选项卡界面,并设置了以下jQuery函数来处理选项卡的点击事件。
$(document).ready(function () {

    $('a#foo').click(function() {
        //content, various calls
        return false;
    });
});

上面是我选项卡的一个示例,其他选项卡也在同一文档就绪块中。我需要做的是使当前选定的选项卡无法重新点击,并且在某些情况下,如果需要,可以手动禁用选项卡。我通过以下方式实现了这一点:
$('a#play').unbind('click');    

这个方法很好用,它可以禁用选项卡,但问题是如何重新绑定原来的点击操作。我通过bind函数实现了这一点:

$('a#foo').bind('click', function() {
//the same content and calls as before
return false;
});

这也完全可行,但随着我向UI添加选项卡,它变得越来越混乱。即时解决方案似乎是将该函数创建为变量,然后将其传递到初始点击创建和绑定事件中。就像这样:

var Foo = new function() {
    //same content and calls as before
    return false;
}

$('a#foo').click(Foo());

$('a#foo').bind(Foo());

出于某种原因,这似乎会导致浏览器崩溃问题。在这种情况下,是否无法将函数作为变量传递,或者我只是做错了?或者,有更好的方法来实现我所寻找的结果吗?谢谢。

6个回答

7
$('a#foo').click(Foo());

$('a#foo').bind(Foo());
Foo提供了函数本身,但在其后添加()表示您正在调用该函数而不是传递函数本身。由于您正在调用该函数,因此false最终被传递给clickbind,显然不会产生任何效果。您的其他问题可能源于模拟两次切换到该选项卡(两次调用事件处理程序)。
var Foo = function() {
    //same content and calls as before
    return false;
}

$('a#foo').click(Foo);

$('a#foo').bind(Foo);

^^ 应该符合您的要求。


另外,有没有更好的方法来实现我想要的结果?

目前我们所知道的关于您的设计只有使用点击事件处理程序来切换选项卡。那很棒,但如果您发布 Foo 中的代码,我们应该能够提供更深入的答案。:D


编辑:感谢 SLaks♦ 注意到我错过的函数声明中的 new。我会在他的解释中添加更多细节:

当您编写 var foo = new function(...) { ... } 时,您正在创建一个函数字面量,然后将其作为构造函数进行调用。

它相当于

var SomeClass = function(...) { ... }; var foo = new SomeClass;

没有 SomeClass 哑变量。

像您预期的那样,function() {} 是一个匿名函数。在 javascript 中,new 有点令人困惑。当您调用一个函数并在其前面加上 new 时,您正在使用该函数来实例化在函数中定义的类的实例。在 JS 中,与大多数其他语言不同,一个类的整个定义都在一个构造函数中,从中设置所有实例变量,如下所示:

Foo = function() { 
    this.a = "lala";
    this.b = 5;
}

为了使'class'的实例方法生效,您需要使用原型属性。不过,我刚刚意识到自己偏离了主题。在这里这里阅读更多信息。:D


哇,整个线程都非常有用/方便。我甚至从未意识到JS函数是这样工作的。非常感谢大家和@CrazyJugglerDrummer的付出,一切都很完美! - keybored

3

在使用函数时,您需要从函数定义中删除new并停止调用该函数。

当您编写var foo = new function(...) { ... }时,您正在创建一个函数文字,然后将其作为构造函数进行调用。

这等价于

var SomeClass = function(...) { ... };
var foo = new SomeClass;

不需要使用SomeClass虚拟变量。

你只需将函数文字赋值给变量即可。


当你写.click(foo())时,你正在调用foo,并将结果传递给click
除非foo返回一个函数,否则这不是你想要的。

你需要通过删除括号来传递foo本身。


3

首先,click接受一个函数作为参数,但是你在调用时不需要加(),因为click会在准备好时运行该函数。如果添加(),则直接调用该函数。

其次,bind需要一个字符串(绑定到哪个事件)和一个函数(如上所述)...

请使用以下方式:

function Foo() {
    //same content and calls as before
    return false;
}


$('a#foo').click(Foo);    
$('a#foo').bind('click', Foo);

希望能对您有所帮助 :)

3

尝试:

var foo = function() // not "new function", as this creates an object!
{
    return false;
}

$("a#foo").click(foo); // not "Foo()", as you can't call an object!

为了实现您所需的更好的结果,您可以在每个选项卡上都添加一个类,例如.tab。这样,您只需要执行以下操作:

$("a.tab").click(function() { return false; });

...无需使用许多id就可以完成。


2
采用不同的方法,不要使用 unbind()
我假设选项卡都在一个公共容器中。如果是这样,只需使用 delegate()(docs) 方法在容器上放置处理程序。
以下是通用代码示例:
$('#container').delegate('.tab:not(.selected)', 'click', function() {
    $(this).addClass('selected')
           .siblings('selected').removeClass('selected');
    // rest of the tab code
});

这将仅触发未具有.selected类的.tab元素上的点击。您需要根据您的特定代码进行修改。


0

添加括号调用函数,但如果你想让它更酷一些,你可以使Foo返回要绑定的函数。

function Foo(){

    return function(){
        //your onclick event handler here.
    };
}

$('a#bar').bind(Foo())

这个程序利用了JavaScript的函数编程方面之一——闭包,这很酷,但不如其他答案高效。你应该研究一下闭包,因为它们可以用来创造一些很酷的东西。 http://www.javascriptkit.com/javatutors/closures.shtml

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