JavaScript-在图像加载函数中设置对象的属性,在函数外部不设置属性 有时候JavaScript对我没有意义,考虑下面的代码,生成基于X/Y瓦片的照片拼接。我试图在下载每个马赛克图像后将.Done属性设置为true,但由于某些原因,它始终为false,我做错了什么 var tileData = []; function generate() { var image = new Image(); image.onload = function() { // Build up the 'tileData' array with tile objects from this Image for (var i = 0; i < tileData.length; i++) { var tile = tileData[i]; var tileImage = new Image(); tileImage.onload = function() { // Do something with this tile Image tile.Done = true; }; tileImage.src = tile.ImageUrl; } }; image.src = 'Penguins.jpg'; tryDisplayMosaic(); } function tryDisplayMosaic() { setTimeout(function() { for (var i = 0; i < tileData.length; i++) { var tile = tileData[i]; if (!tile.Done) { tryDisplayMosaic(); return; } } // If we get here then all the tiles have been downloaded alert('All images downloaded'); }, 2000); } var tileData=[]; 函数生成() { var image=新图像(); image.onload=函数() { //使用此图像中的平铺对象构建“平铺数据”数组 对于(变量i=0;i
现在由于某种原因,JavaScript-在图像加载函数中设置对象的属性,在函数外部不设置属性 有时候JavaScript对我没有意义,考虑下面的代码,生成基于X/Y瓦片的照片拼接。我试图在下载每个马赛克图像后将.Done属性设置为true,但由于某些原因,它始终为false,我做错了什么 var tileData = []; function generate() { var image = new Image(); image.onload = function() { // Build up the 'tileData' array with tile objects from this Image for (var i = 0; i < tileData.length; i++) { var tile = tileData[i]; var tileImage = new Image(); tileImage.onload = function() { // Do something with this tile Image tile.Done = true; }; tileImage.src = tile.ImageUrl; } }; image.src = 'Penguins.jpg'; tryDisplayMosaic(); } function tryDisplayMosaic() { setTimeout(function() { for (var i = 0; i < tileData.length; i++) { var tile = tileData[i]; if (!tile.Done) { tryDisplayMosaic(); return; } } // If we get here then all the tiles have been downloaded alert('All images downloaded'); }, 2000); } var tileData=[]; 函数生成() { var image=新图像(); image.onload=函数() { //使用此图像中的平铺对象构建“平铺数据”数组 对于(变量i=0;i,javascript,javascript-objects,Javascript,Javascript Objects,现在由于某种原因,tile对象上的.Done属性始终为false,即使它在tileImage.onload=function()中显式设置为true。我可以确保调用此函数,因为我在其中放置了一个alert()调用。现在它只是卡在一个不断调用trydisplaymosic()的无限循环中 另外,如果我在调用trydisplaymosic()之前放置了一个循环,并在该循环中设置了.Done=true,则.Done属性为true,并且警报(“下载的所有图像”)将被调用。顶部循环中的变量“tile”由您
tile
对象上的.Done
属性始终为false,即使它在tileImage.onload=function()中显式设置为true。我可以确保调用此函数,因为我在其中放置了一个alert()
调用。现在它只是卡在一个不断调用trydisplaymosic()
的无限循环中
另外,如果我在调用trydisplaymosic()
之前放置了一个循环,并在该循环中设置了.Done=true
,则.Done
属性为true,并且警报(“下载的所有图像”)代码>将被调用。顶部循环中的变量“tile”由您创建的每个“onload”函数共享;换句话说,就是同一个变量。尝试以下方法,为每个变量指定自己的变量:
tileImage.onload = (function(myTile) {
return function()
{
// Do something with this tile Image
myTile.Done = true;
};
})(tile);
为什么会这样?因为与C或Java不同,在循环中这样声明“tile”不会使其作用域局限于循环体的语句块。在Javascript中,唯一能为您提供作用域的是函数体。我看到的是在循环中创建闭包,这就是。为了避免这种情况,您可以在循环之外创建一个更通用的闭包,该闭包处理所有加载事件,并在加载所有映像后执行一个函数:
// This array must be filled somewhere...
var tileData = [];
var ImageLoader = function(){
var numOfImages = 0;
var numLoaded = 0;
var callBack = function(){};
function imageLoaded(){
numLoaded++;
if(numLoaded===numOfImages){
// All images are loaded, now call the callback function
callBack.call(this);
}
}
function init(numberOfImages, fn){
numOfImages = numberOfImages;
callBack = fn;
}
return {
imageLoaded: imageLoaded,
init: init
};
}();
function tryDisplayMosaic(){
alert('All images downloaded');
}
function generate(){
// (1) Set the number of images that are to be loaded and (all tiles + penguin)
// (2) Set the function that must be called after all images are loaded
ImageLoader.init(tileData.length+1, tryDisplayMosaic);
// Load this Penguins image
var image = new Image();
image.src = 'Penguins.jpg';
image.onload = ImageLoader.imageLoaded;
// Go through each image and load it
for (var i=0; i<tileData.length; i++) {
image = new Image();
image.src = tileData[i].ImageUrl;
image.onload = ImageLoader.imageLoaded;
}
}
//此数组必须在某处填充。。。
var tileData=[];
var ImageLoader=函数(){
var numOfImages=0;
var numload=0;
var callBack=function(){};
函数imageLoaded(){
numload++;
if(numload==numOfImages){
//所有图像都已加载,现在调用回调函数
回调。调用(此);
}
}
函数初始化(numberOfImages,fn){
numOfImages=numberOfImages;
回调=fn;
}
返回{
imageLoaded:imageLoaded,
init:init
};
}();
函数tryDisplayMosaic(){
警报(“下载的所有图像”);
}
函数生成(){
//(1)设置要加载的图像数量和(所有平铺+企鹅)
//(2)设置加载所有图像后必须调用的函数
ImageLoader.init(tileData.length+1,tryDisplayMosaic);
//加载这个企鹅图片
var image=新图像();
image.src='Penguins.jpg';
image.onload=ImageLoader.imageLoaded;
//浏览每个图像并加载它
对于(var i=0;iIftileData
与您的代码中一样是空的,那么我确信这会正常工作,因为for循环没有执行。但是如果它不是空的,那么它将不工作,因为您在循环中定义了函数。您能告诉我们tileData
到底是什么吗?这非常有效,谢谢!尽管语法非常简单对我来说,我需要学习更多的JavaScript。