我一直在尝试创建一个基于HTML5的小例子,但我遇到了一些问题。我想在<canvas>
上渲染一块石头,但是这个Javascript对象将无法正常工作。
function ImageData() {
this.image_names = ["rock1"];
this.images = new Array();
this.loadResources = function () {
for (var i = 0; i < this.image_names.length; i++) {
var img = new Image();
img.onload = (function (a) {
a.images[a.image_names[i]] = img;
console.log(a.images); //log is successful, image is in array
})(this);
img.src = "images/" + this.image_names[i] + ".png";
}
}
}
它的用途如下:
var a = new ImageData();
a.loadResources();
var rock1_image = a.images["rock1"]; //the "rock1.png" image
如果您尝试通过控制台访问该对象,您会在确定已加载图像后看到图像阵列中没有图像。我无法弄清楚为什么它不起作用。我已经多次查看了它。
编辑:这是我最后的工作成果:
function ImageData() {
this.image_names = ["rock1"];
this.images = new Array();
this.loadResources = function (callback) {
for (var i = 0; i < this.image_names.length; i++) {
var img = new Image();
img.onload = (function (a, i) {
return function() {
a.images[a.image_names[i]] = img;
if (i == (a.image_names.length - 1)) callback();
};
})(this, i);
img.src = "images/" + this.image_names[i] + ".png";
}
}
}
答案 0 :(得分:2)
我冒昧地说,在将其添加到阵列之前,您正试图访问它。我建议您在loadResources
方法中添加一个回调或其他内容,以确保它在您尝试访问之前就已存在。
this.loadResources = function (callback) {
for (var i = 0; i < this.image_names.length; i++) {
var img = new Image();
img.onload = (function (a, i) {
return function() {
a.images[a.image_names[i]] = img;
console.log(a.images); //log is successful, image is in array
callback();
};
})(this, i);
img.src = "images/" + this.image_names[i] + ".png";
}
}
然后
var a = new ImageData();
var rock1_image;
a.loadResources(function() {
rock1_image = a.images["rock1"];
// do whatever you need to do with the image in here.
});
另外,@ Igor提到了什么。我完全错过了。我调整了上面的代码,这样您就可以保留this
范围而无需在其他地方设置。
更新以处理@RobD提出的i
问题。
答案 1 :(得分:2)
在(this)
处理程序定义后删除onload
。您实际上是在立即调用此函数,将undefined
(因为它不返回任何内容)指定为img.onload
值。
答案 2 :(得分:1)
在代码中:
> function ImageData() {
> this.image_names = ["rock1"];
> this.images = new Array();
> this.loadResources = function () {
> for (var i = 0; i < this.image_names.length; i++) {
> var img = new Image();
> img.onload = (function (a) {
此功能将立即运行且不返回值,因此将分配 undefined 。所以在任务中没有意义,只需运行代码即可。
> a.images[a.image_names[i]] = img;
Images是一个用作普通对象的数组。那么最好使用普通对象。
> console.log(a.images); //log is successful, image is in array
> })(this);
由于IIFE,必须传入外部此。删除IIFE并且无需传递此。如果对函数的引用存储在函数中,则调用函数的方式无关紧要(即,您不必在调用中设置 this )。
> img.src = "images/" + this.image_names[i] + ".png";
> }
> }
> }
您可能需要以下内容:
function ImageData() {
this.image_names = ['rock1'];
this.images = {};
imageData = this;
this.loadResources = function (callback) {
for (var i = 0; i < imageData.image_names.length; i++) {
var img = new Image();
imageData.images[a.image_names[i]] = img;
img.src = 'images/' + this.image_names[i] + '.png';
if (callback) {
img.onload = callback;
}
}
}
}
var a = new ImageData();
a.loadResources(function(){console.log('loaded: ' + this.src);}); // loaded: …
window.onload = function() {
document.body.appendChild(a.images.rock1); // image appears in document
}
答案 3 :(得分:0)
我还没有测试过您的代码,但我想这就是问题所在: 您正在尝试在加载图像之前访问该图像。您可以在加载之后使用回调事件处理程序,如:
var data = new ImageData();
data.loadResources(function(imgObj){
// imgObj is the newly load image here. Have fun with it now!
})