用RaphaelJS库绘制一组圆圈。
对于每个圆圈,我想创建一个传递变量的onclick
函数,但在此函数中,我的变量是未定义的。
有什么问题?
这是我的代码:
//children is an array such as [1,2,4[5,6,7]]
for (var i = 0; i < children.length; i++) {
var array = children;
alert("ARRAY[0]===" + array[0])
var st = space2Draw.set();
st.push(space2Draw.circle(xChildren, yChildren, 20).click(function (array) {
//array[i] is undefined
alert("ARRAY[i]===" + array[i]);
//retrive(array[i]);
}),
LineRoot(xRadice, yRadice, xChildren, yChildren, space2Draw));
space2Draw.text(xChildren, yChildren, children[i]).attr({
fill: "white"
});
st.attr({
fill: "red"
});
xChildren += 50;
}
答案 0 :(得分:2)
您的点击回调不应该有“数组”参数,它会覆盖父作用域中的“数组”变量。你可以删除参数,它应该没问题。
我认为你的另一个问题是我总是在你的点击回调中使用children.length(因为函数范围实际上会在循环结束时关闭。更多信息here)。您应该创建一个辅助函数来为您创建回调。
您可以尝试这样的事情:
//children is an array such as [1,2,4[5,6,7]]
for (var i = 0; i < children.length; i++) {
var array = children;
alert("ARRAY[0]===" + array[0])
var st = space2Draw.set();
st.push(space2Draw.circle(xChildren, yChildren, 20).click(getCallback(array , i)),
LineRoot(xRadice, yRadice, xChildren, yChildren, space2Draw));
space2Draw.text(xChildren, yChildren, children[i]).attr({
fill: "white"
});
st.attr({
fill: "red"
});
xChildren += 50;
}
function getCallback(array , i){
return function () {
alert("ARRAY[i]===" + array[i]);
}
}
答案 1 :(得分:1)
你应该这样做:
...
st.push(space2Draw.circle(xChildren, yChildren, 20).click((function (array, i) {
return function () {
//array[i] is undefined
alert("ARRAY[i]===" + array[i]);
//retrive(array[i]);
}
}(array, i)));
...
其原因在于javascript中,范围是由函数定义的,而不是由块定义的。
您的回调可以访问array
和i
(以及其他变量),但是当回调执行时,i
等于children.length
,因为循环已完成迭代。
通过使用IIFE(立即调用函数表达式),我们创建了一个新的范围,并且回调可以访问array
和i
的当前值。
此外,click
函数通过传递event
对象作为第一个参数来调用回调,因此我们的IIFE应该返回此
return function (event) {
// access array and i by closure
// event is the event representing the click
// event, provided by Raphael
// do something
}