我有一个菜单类从收到的json文件中加载数据。
在构造函数中我构建菜单,所以我有一个for循环与此(提取部分)js:
for (var i = 0; i<data.length; i++)
{
var btn = $('<div>'+data[i].label+'</div>').appendTo(object.container);
btn.click(function()
{
if($('.blockingFrame').length == 0)//pas de blocking
{
data[i].action()
}
});
}
现在,显然这不起作用,因为在运行时数据[i]不再存在... data [i] .action包含一个有效的js函数。
这有效,但不包含条件..:
for (var i = 0; i<data.length; i++)
{
var btn = $('<div>'+data[i].label+'</div>').appendTo(object.container);
btn.click(data[i].action);
}
所以我认为我可以将这个动作存储在jquery对象中并像这样调用它,但它不起作用:
for (var i = 0; i<data.length; i++)
{
var btn = $('<div>'+data[i].label+'</div>').appendTo(object.container);
btn.action = data[i].action;
btn.click(function()
{
if($('.blockingFrame').length == 0)//pas de blocking
{
$(this).action();
}
});
}
我带来的部分解决方案是将操作存储在另一个事件中,比如dblclick,并在条件内触发dblclick,但这种接缝难看。
知道怎么做吗?
答案 0 :(得分:1)
使用立即执行的函数创建一个包含i
的闭包。
for (var i = 0; i<data.length; i++) {
var btn = $('<div>'+data[i].label+'</div>').appendTo(object.container);
btn.click(function(i) {
return function() {
if($('.blockingFrame').length == 0)//pas de blocking {
data[i].action();
}
}(i));
}
答案 1 :(得分:1)
for
循环don't work properly with closures。请考虑使用迭代器方法:
$.each(data, function(index, elem) {
var btn = $('<div>'+elem.label+'</div>').appendTo(object.container);
btn.click(function()
{
if($('.blockingFrame').length == 0)//pas de blocking
{
elem.action()
}
});
}
迭代器通常比for
循环更优雅,更紧凑,尤其是当它们嵌套时。
如果btn = $(...)
是临时jquery对象,那么您的上一个代码段不起作用的原因会在您离开作用域后消失,并且已分配给它。稍后调用click
处理程序时,您将通过$(this)
创建一个新的jquery对象,该对象不会执行上一步中的更改。如果要将任何数据永久保留在元素上,请使用data
方法 - 但在这种情况下,不需要这样做。