我在寻找问题的解决方案时发现了类似的问题,但我认为它并不是我想要的。
使用jQuery的.on()对于动态创建的元素上的事件绑定并不是很明智,但是在尝试传递不同的参数来调用不同的函数时我遇到了困难。在阅读https://developer.mozilla.org/en/JavaScript/Guide/Closures之后,我想出了以下工作示例,但我想知道它是最好的方法,还是有更优雅的解决方案?
另外我经常读到,由于漏洞问题,使用eval()不是最佳做法,但还有另一种方法来构建动态函数名称吗?
编辑:
非常感谢大家的回答!其中一个答案是否被删除了?我喜欢那个,因为提示将参数存储在属性中。再次感谢所有人!
答案 0 :(得分:3)
事件点委托是你不需要将事件绑定到每个单独的元素(或多次绑定到同一个元素),只需要一次绑定到公共父元素,如下所示:
function createLinks() {
var $container = $("#container"),
links = "";
for (var i=0; i < 4; i++) {
links += '<a class="linklink" href="#">Link_' + i + '</a>';
}
$container.html(links).on( "click", ".linklink", function(){
console.log( "fn action"+$(this).index());
});
}
createLinks();
为避免使用eval
,您可以拥有一组函数并通过索引调用它们:
arrayOfFunctions[ $(this).index() ]();
答案 1 :(得分:2)
如果每个动作函数实际上必须是一个不同的函数(而不是一个函数根据传递给它的索引而有所不同),那么我就是通过在链接上放置一个属性并在其上获取它来实现的。点击您可以在此处查看的内容:http://jsfiddle.net/jfriend00/gFmvG/。
function action0(){ console.log("fn action0"); }
function action1(){ console.log("fn action1"); }
function action2(){ console.log("fn action2"); }
function action3(){ console.log("fn action3"); }
var actions = [action0, action1, action2, action3];
function createLinks() {
var $container = $("#container"),
links = "";
for (var i=0; i < 4; i++) {
links += '<a id="link_' + i + '" href="#" data-num="' + i + '">Link_' + i + '</a>';
$container.on("click", '"#link_' + i + '"', function() {
actions[$(this).data("num")]();
});
}
$container.html(links);
}
createLinks();
如果您不必为每个操作都有单独的功能,我会这样做,您可以在此处看到:http://jsfiddle.net/jfriend00/Z8Rq6/。
function doAction(index) {
console.log("fn action" + index);
}
function createLinks() {
var $container = $("#container"),
links = "";
for (var i=0; i < 4; i++) {
links += '<a id="link_' + i + '" href="#" data-num="' + i + '">Link_' + i + '</a>';
$container.on("click", '"#link_' + i + '"', function() {
doAction($(this).data("num"));
});
}
$container.html(links);
}
createLinks();
这也可以通过锁定索引值的执行闭包来完成,但我发现语法的可读性稍差(读取代码需要太多的脑循环并知道它在做什么)所以我更喜欢这种方式属性。
答案 2 :(得分:1)
看起来你原来的问题是你想调用一个函数,其名称将由传入的参数决定。这些函数是否全局范围内?如果是这样,我会这样做:
function helpCallback(index) {
return function() {
window['action' + index]();
}
}
这有一个额外的好处,如果您想要将参数传递给actionX,可以通过在索引之后传递这些参数并进行以下修改来实现此目的
function helpCallback(index) {
var args = arguments;
return function() {
window['action' + index].apply(null, [].slice.call(args, 1));
}
}
因此helpCallback(1, "foo");
会返回一个调用action1('foo')
答案 3 :(得分:1)
将您的功能放在对象中
var myFuncs = {
action0:function(){ console.log("fn action0"); },
action1:function(){ console.log("fn action1"); },
action2:function(){ console.log("fn action2"); },
action3:function(){ console.log("fn action3"); }
};
var funcNumber = "3";
for (var i=0; i < 4; i++)
{
links += '<a id="link_' + i + '" href="#">Link_' + i + '</a>';
(function(myI)
{
$container.on("click", '"#link_' + i + '"', function()
{
myfuncs["action"+funcNumber](mI);
});
})(i);
}
当然,如果它们是在全球范围内制作的,那么你也可以这样做
for (var i=0; i < 4; i++)
{
links += '<a id="link_' + i + '" href="#">Link_' + i + '</a>';
(function(myI)
{
$container.on("click", '"#link_' + i + '"', function()
{
window["action"+funcNumber](mI);
});
})(i);
}
答案 4 :(得分:0)
我个人不打算创建ID然后引用它们。为什么不在绑定中使用闭包到你创建的实际元素。
例如,您可以执行类似
的操作function createLinks() {
var $container = $("#container");
for (var i=0; i < 4; i++) {
var link = $('<a href="#link' + i + '">Link_' + i + '</a>');
$container.append(link);
(function(){
var index = i;
link.click(function(){
alert("Do my thing " + index);
});
})();
}
}
createLinks();