我写了一个小测试程序,探索我的问题,它按照我期望的方式工作,打印"四,五,六"。
var foo = function() {
console.log("just one more test")
var destination = new Array;
data = [ "four", "five" , "six" ]
var parent = [ 0, 1, 2 ];
var something;
parent.forEach(function(element) {
something = data[element];
destination.push(something);
})
destination.forEach(function (thing) {
console.log(thing);
})
}
foo();
但是在我的真实代码中,当我把东西推到我的可点击的'数组,所有条目都变异为' clicker'的当前值。变量。我的' scheme_list'中有3个条目,它们正确绘制,但是当我尝试构建要点击的区域时,在循环的每次迭代中#34;在循环中#34;为每个实例打印刚刚推送到数组的值。也就是说,' clicker'已经在循环中更改为clicker的当前值。我试图理解我的真实代码和我的测试代码之间的区别。或者,更重要的是,如何修复我的真实代码。
var layout_color_schemes = function(scheme_list) {
var canvas = document.getElementById('color_picker_canvas');
var ctx = canvas.getContext('2d');
var x_upper_left = 5;
var y_upper_left = 5;
var width = 200;
var height = 30;
var clickables = new Array;
var clicker = {};
clicker.rect = {};
clicker.rect.width = width;
clicker.rect.height = height;
scheme_list.forEach(function(row) {
var grad = ctx.createLinearGradient(0, 0, 100, 0);
var cscheme = jQuery.parseJSON(row.json);
cscheme.forEach(function(color_point) {
grad.addColorStop(color_point[0], 'rgb(' + color_point[1] + ','
+ color_point[2] + ',' + color_point[3] + ')');
})
ctx.fillStyle = grad;
ctx.fillRect(x_upper_left, y_upper_left, width, height);
clicker.rect.x = x_upper_left;
clicker.rect.y = y_upper_left;
clicker.scheme = cscheme;
clicker.name = row.name;
clickables.push(clicker);
printf("clickables size = %d", clickables.length)
for (index = 0; index < clickables.length; ++index) {
printf("Index is %d", index)
printf("in the loop %j", clickables[index])
}
ctx.fillStyle = 'black'
ctx.fillText(row.name, x_upper_left + width + 10, 5 + y_upper_left
+ (height / 2));
y_upper_left = y_upper_left + height + 10;
});
clickables.forEach(function(area) {
printf("before call clickable area = %j", area)
});
wire_clickables(clickables);
};
function wire_clickables(clickables) {
clickables.forEach(function(area) {
if (area.hasOwnProperty('rect')) {
printf("wiring a clickable %j", area);
$("#color_picker_canvas").mousemove(function(e) {
var inside = false;
var offsetX = e.pageX - $(this).position().left;
var offsetY = e.pageY - $(this).position().top;
if (area && contains(area.rect, offsetX, offsetY)) {
document.body.style.cursor = 'pointer'
}
else {
document.body.style.cursor = 'default'
}
})
}
})
}
function contains(rect, x, y) {
return (x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y
+ rect.height)
}
答案 0 :(得分:2)
clicker
对象存在于循环之外,因此您所做的就是将相同的引用推送到clickables
。相反,您想要推送它的副本。有很多方法可以做到这一点,但在你的情况下,这可能是最简单的方法之一:
替换
clickables.push(clicker);
与
clickables.push(JSON.parse(JSON.stringify(clicker));
或者,在循环内移动clicker
声明和初始化。