2012-01-05 83 views
2

我试图通过JavaScript循环对象,并将该对象的所有子对象添加到HTML5画布。JavaScript循环/范围问题与Image.onload()

画布位正在工作,没有问题,但由于某种原因,我的所有图像最终都是相同的大小 - 最后一个子对象'背景'的大小。我假设它与我的循环和'this'的范围有关,但我真的不知道要改变什么;

var stage; 
var items = { 
    head: {image: null, path: "images/avatar-elements/head01.png", w:200, h:200}, 
    hair: {image: null, path: "images/avatar-elements/hair01.png", w:200, h:200}, 
    nose: {image: null, path: "images/avatar-elements/nose01.png", w:200, h:200}, 
    eyes: {image: null, path: "images/avatar-elements/eyes01.png", w:200, h:200}, 
    eyebrows: {image: null, path: "images/avatar-elements/eyebrows01.png", w:200, h:200}, 
    ears: {image: null, path: "images/avatar-elements/ears01.png", w:200, h:200}, 
    background: {image: null, path: "images/avatar-elements/background01.png", w:500, h:370} 
}; 

function initCanvas() { 
    stage = new Kinetic.Stage("canvas", 500, 370); 
    makeBasis(); 
} 


function makeBasis() { 
    for(i in items) { 
     var img = new Image(); 
     img.onload = function() { 
      items[i].image = makeCanvasImage(this, items[i].w, items[i].h); 
     } 
     img.src = items[i].path; 
    } 


} 

function makeCanvasImage(tar, w, h) { 
    var theImage = new Kinetic.Image({ 
     imageObj: tar, 
     x: 250 - (w/2), 
     y: 185 - (h/2), 
     width: w, 
     height: h 
    }); 
    stage.add(theImage); 
    return theImage; 
} 

initCanvas(); 
+1

的可能重复[关闭的Javascript内循环 - 简单实用的例子(http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example ) – 2012-01-05 10:37:33

回答

7

错误在makeBasis()中。循环所有图像后,我被设置为最后 - 经典闭合问题。尝试使用这样的:

function makeBasis() { 
    for(i in items) { 
     var img = new Image(); 
     img.onload = (function (nr) { 
      return function() { 
       items[nr].image = makeCanvasImage(this, items[nr].w, items[nr].h); 
      } 
     }(i));  
     img.src = items[i].path; 
    } 
} 
+0

美丽,固定它。你能告诉我什么是“返回功能”吗?它是否在图像加载后执行?如果图像没有按照加载的顺序完成加载,会发生什么情况?是不是将错误的图像添加到'items'中的子对象中? – Rein 2012-01-05 10:54:28

+0

@Reinoud:'return function(){...}'返回'function(){...}'定义的函数。这是立即执行的,因为外函数立即执行'(function(){...}())'(注意括号在最后)。 – 2012-01-05 10:59:29

+1

@Felix Kling正好。我知道这很复杂,但是当你阅读和理解例如这:http://www.mennovanslooten.nl/blog/post/62你不会再有这个问题:) – 2012-01-05 11:27:36