JQuery:动态调用函数

时间:2010-12-22 07:18:50

标签: javascript jquery

我已将onClick事件句柄附加到标记。点击后,我想拿起一个属性 - 让我们说,fn;我想把所提到的函数称为属性值。

以下代码不起作用

<html>
<head>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
    <script language="JavaScript">
        var Test = Test? Test : new Object();
        $(document).ready(function(){
            Test.main();
        })
        Test.sub = function(){
            alert('called');
        }
        Test.main = function(){
            $('.caller').click(function(e){
                e.preventDefault();
                var fn = $(this).attr('fn');
                alert('calling: '+fn);
                return fn();
            });
        }
    </script>
</head>
<body>
    <a class="caller" fn="Test.sub" href="#">test call</a>
</body>
</html>

我的问题是

  • 有可能吗?
  • 我做错了什么?
  • 解决这个问题的正确方法是什么?

感谢
NISHANT

2 个答案:

答案 0 :(得分:14)

  

有可能吗?

是。如果您将链接更改为sub

<a class="caller" fn="sub" href="#">test call</a>

然后这个有效:

$('.caller').click(function(e){
    e.preventDefault();
    var fn = $(this).attr('fn');
    alert('calling: '+fn);
    return Test[fn]();
});

您检索的值是一个字符串。如果您喜欢使用括号表示法([]),则可以使用字符串索引对象的属性,因此所有这些都是等效的:

Test.sub();
Test['sub']();
var fn = 'sub';
Test[fn]();
  

我做错了什么?

你快到了。你在一个字符串中有“Test.sub”,但由于它是一个字符串,而不是一个函数,你无法调用它。这就像这样:

"Test.sub"();

....这显然不是你想要的。 : - )

  

解决这个问题的正确方法是什么?

在技术方面,以上解决了这个问题。我的一部分担心在一个属性中有实际的函数名称,并想说“有一个查找表”,但你的Test对象基本上查找表,所以...

旁注:在这种情况下,您可能会看到有人使用eval。通常那是因为他们没有意识到你可以使用括号表示法索引对象。最好避免使用eval


偏离主题#1 :您的属性fn无效(无效=不会validate)。在HTML4及更早版本中,所有自定义属性都是无效的,尽管我见过的每个桌面浏览器都允许它们(浏览器让我们侥幸逃脱)。从HTML5开始,我们听到了对此功能的需求,我们可以拥有有效的自定义属性,但它们必须以data-开头,因此验证器知道它们是自定义的。因此,如果验证是您工作流程的一部分(并且通常是一个好主意),您可以使用data-fn="sub"而不是fn="sub"More here.


偏离主题#2 :如果您想保存一些输入内容,请使用{}而不是new Object()。 E.g:

var Test = Test? Test : {};

如果您想保存更多,请使用the curiously-powerful || operator

var Test = Test || {};

答案 1 :(得分:-1)

试试这个:

<a class="caller" fn="Test.sub()" href="#">test call</a>

$('.caller').click(function(e){
    e.preventDefault();
    var fn = eval($(this).attr('fn'));
    fn;
});