我正在尝试编写一个通用表生成器,我可以告诉它在每个单元格的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上的第一篇文章,所以请保持温和......
答案 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);
})
});
})
注意:有很多方法可以做到这一点。