image.onLoad - 在触发此事件之前,我应该如何保持数据可用?

时间:2012-03-27 19:13:02

标签: javascript

//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'事件期间访问这些属性。不过,我找不到替代方案是不成功的。我想知道是否有人有任何想法。感谢。

1 个答案:

答案 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);