//Draw Icon
for (var i = 0; i < diagram.Children.length; i++) {
if (diagram.Children[i].Icon != -1) {
var myImage = new Image();
myImage.xOffset = diagram.Children[i].Offset.X;
myImage.yOffset = diagram.Children[i].Offset.Y;
myImage.componentName = diagram.Children[i].Name;
myImage.componentLevel = diagram.Level;
myImage.componentID = diagram.ID;
myImage.type = diagram.Type;
myImage.onload = function () {
var self = this;
var iconImage = new Kinetic.Image({
image: self,
x: self.xOffset,
y: self.yOffset,
tooltip: CreateTooltip(self.componentName, self.componentID, self.type),
componentLevel: self.componentLevel,
componentID: self.componentID
});
_stage.diagramLayer.add(iconImage);
_stage.diagramLayer.draw();
}
//TODO: IE8+ doesn't support data URI's unless they are defined in css.
//myImage.src = 'data:image/png;base64,' + diagram.Children[i].Icon;
myImage.src = '../PlanView/RenderIcon?IconID=' + diagram.Children[i].Icon;
}
}
在加载图像之前必须将我的数据存储为图像属性似乎违反直觉,只是为了能够在'onload'事件期间访问这些属性。不过,我找不到替代方案是不成功的。我想知道是否有人有任何想法。感谢。
答案 0 :(得分:2)
变量在范围内。问题是i
(以及在循环中重新分配的任何其他变量)将在事件触发之前发生变化。如果您只是将该代码拉入函数中,问题就解决了。
for (var i = 0; i < diagram.Children.length; i++) {
if (diagram.Children[i].Icon != -1) {
doImageStuff(diagram, i);
}
}
...
function doImageStuff(diagram, i){
var myImage = new Image();
var xOffset = diagram.Children[i].Offset.X;
/* etc. */
myImage.onload = function () {
// do stuff and use variables such as xOffset here
}
}
这样,函数中的i
不会随着循环的继续而改变。
编辑:要解决有关匿名函数的评论中的问题。你可以做这样的事情,虽然我觉得它有点乱:
for (var i = 0; i < diagram.Children.length; i++) {
if (diagram.Children[i].Icon != -1) {
(function(diagram, i){
var myImage = new Image();
var xOffset = diagram.Children[i].Offset.X;
/* etc. */
myImage.onload = function () {
// do stuff and use variables such as xOffset here
}
})(diagram, i);
}
}
还有其他替代品,我发现它甚至更麻烦,例如返回函数的匿名函数。
myImage.onload = (function (diagram, i) {
return function(){
// do stuff here using the variables
}
})(diagram, i);