如何将存储在字符串中的函数添加到jquery .click事件中

时间:2013-01-25 10:58:01

标签: c# javascript jquery

我正在尝试编写一个通用表生成器,我可以告诉它在每个单元格的onclick事件中调用的函数。然后在页面的其他位置定义该函数。

问题是我无法在适当的时刻获取页面来评估功能。我希望它在构建DOM时将我的字符串转换为函数,而不是在它触发click事件时。也许这在Javascript / JQuery中是不可能的?

我最初在C#中编写服务器端的代码的简化版本是:

string functionCall = "DoSomething(4);";
TableCell detailCell = new TableCell();
detailCell.Attributes.Add("onClick", functionCall);
functionCall = "DoSomething(5);";
detailCell = new TableCell();
detailCell.Attributes.Add("onClick", functionCall);

当它在浏览器中呈现为html时,它会起作用。它变成了:

 function DoSomething(p)
 {
      alert(p);
 }

<td onclick="DoSomething(4)"></td>
<td onclick="DoSomething(5)"></td>

我想在Javascript中复制此功能。

如果我这样做:

var functionCall = 'DoSomething(4);';
$('#detailCell').attr('onclick', functionCall);

由于某些原因,它不会在IE7中触发事件,但会在Chrome中触发它。

如果我这样做:

var functionCall = 'DoSomething(4);';
$('#detailCell1').click(function () { eval(functionCall); });
functionCall = 'DoSomething(5);';
$('#detailCell2').click(function () { eval(functionCall); });

然后在添加click事件时,它不会将functionCall更改为一段文本。相反,它会在单击单元格时验证functionCall。这意味着functionCall的值现在是错误的。

e.g。它总是做DoSomething(5),即使我点击detailCell1,因为那是functionCall的最后一个值。

如果我这样做:

var functionCall = 'DoSomething(4);';
$('#detailCell1').click(eval(functionCall));

它在添加click事件时立即在functionCall中运行该函数,而不是在单击它时。

我希望这有点意义,因为很难解释。

基本上我只是希望能够做到

<td onclick="any javascript I feel like storing in a string"></td>

使用JQuery。

这甚至可能吗?

这是我在stackoverflow上的第一篇文章,所以请保持温和......

4 个答案:

答案 0 :(得分:2)

试试这个......

var functionCall = 'DoSomething(4);';

$('#detailCell1').click((function (code) {
  return function () { 
     eval(code); 
  };
}(functionCall)));

这里发生的是您在创建处理程序时通过将其分配给参数“code”来捕获字符串。

在当前场景中,单击处理程序在单击时使用字符串的值,而不是在创建处理程序时使用。

这称为闭包!

(function (code) {
  return function () { 
     eval(code); 
  };
}(functionCall));

functionCall值分配给代码参数。 现在,当您更改functionCall时,代码参数仍然引用旧值。

答案 1 :(得分:0)

不清楚为什么函数调用应该在字符串中。正如我所看到的,你有许多单元格应该为每个单元格激活一个具有不同参数的函数。

在这种情况下,我会做下一步:

TableCell detailCell = new TableCell();
detailCell.Attributes.Add("class", "detailCell");
detailCell.Attributes.Add("data-num", "4");

detailCell = new TableCell();
detailCell.Attributes.Add("class", "detailCell");
detailCell.Attributes.Add("data-num", "5");

而不是js中的某个地方:

$(function() {
    $(".detailCell").click(function(){
        DoSomething($(this).data("num"));
    });
})
需要在表格单元格上

class才能轻松地将点击处理程序分配给所有细节单元格,因此您无需编写如下内容:

$('#detailCell1').click(function () { DoSomething(4); });
$('#detailCell2').click(function () { DoSomething(5); });

detailCell.Attributes.Add("data-num", "5");允许输入应该用作DoSomething参数的数字。您可以在此行中看到它:正在使用DoSomething($(this).data("num")); jQuery.data函数。并且this将指向要点击的元素。 $(function() {}) - 这是jQuery.ready函数的简写。使用它可以保证在页面准备好使用时,该函数内的代码将被执行。

答案 2 :(得分:0)

而不是首先将其创建为字符串,然后尝试评估该字符串,您只需创建一个函数值(函数在JS中也是对象)

所以而不是

var functionCall = 'DoSomething(4);';
$('#detailCell1').click(eval(functionCall));

DO

$('#detailCell1').click(function(e){DoSomething(4);});

这会为每次点击创建一个新功能。 (在你的情况下,你可以省略e参数,只需要进行任何需要更容易的更改

如果您有一组参数,则可以创建工厂方法

var doSomethingFactory = function(num){
    return function(e) { DoSomething(num);};
}
$('#detailCell1').click(doSomethingFactory(4));

答案 3 :(得分:0)

根据我的理解,你必须使用不同的参数调用不同的函数。要实现这一点,你要生成字符串并尝试使用eval()函数调用这些函数。让我们按照以下方式进行:

1.只需将那些functioncalls字符串作为数组传递,这样在加载时你的javascript代码如下所示,

var functioncalls = ['DoSomething(1)','DoSomethingMore(1,2)','DoDifferent("hello world")'];

2.然后在javascript中循环你的函数调用数组并将它们分配给不同的click事件。为了避免复杂性,我假设你的选择器是#detailCell0,#detailCell1,#detailCell2等等。然后你的代码如下所示,

$(function(){
      functioncalls.forEach(function(functioncall,index){
          $("detailCell"+index).click(function(){ 
                eval(functioncall);
           })
      });
    })

注意:有很多方法可以做到这一点。