2013-06-04 116 views
13

我一直在浏览大量JavaScript的答案,但是我还没有找到真正解决我的问题的方法。我想要做的是加载图像,获取像素数据,执行分析,然后加载另一个图像以重复该过程。在继续执行脚本之前,JavaScript正在等待图像完全加载

我的问题是我无法预先加载所有图像,因为此脚本必须能够处理大量图像,并且预加载可能太重。所以我一直试图通过一个循环加载一个新的图像,但我坚持在图像加载和将其绘制到画布上下文的脚本之间的竞争条件。至少我非常确定这是发生了什么,因为脚本可以在预先载入图像的情况下正常工作(例如,如果之前在加载页面后刷新)。

正如你所看到的,有几行代码被注释掉了,因为我对JavaScript非常陌生,并且他们没有像我认为的那样工作,但是我不想忘记他们,如果我稍后需要功能。

这是我认为是引起问题的代码片段:

编辑:所以我得到了我的函数如下建议

function myFunction(imageURLarray) { 
    var canvas = document.getElementById('imagecanvas'); 
    console.log("Canvas Grabbed"); 

    if (!canvas || !canvas.getContext) { 
    return; 
    } 

    var context = canvas.getContext('2d'); 

    if (!context || !context.putImageData) { 
    return; 
    } 

    window.loadedImageCount = 0; 
    loadImages(context, canvas.width, canvas.height, imageURLarray, 0); 
} 

function loadImages(context, width, height, imageURLarray, currentIndex) { 
    if (imageURLarray.length == 0 || imageURLarray.length == currentIndex) { 
    return false; 
    } 
    if (typeof currentIndex == 'undefined') { 
    currentIndex = 0; 
    } 

    var currentimage = new Image(); 
    currentimage.src = imageURLarray[currentIndex]; 

    var tempindex = currentIndex; 
    currentimage.onload = function(e) { 

    // Function code here 

    window.loadedImageCount++; 

    if (loadedImageCount == imageURLarray.length) { 

     // Function that happens after all images are loaded here 
    } 
    } 
    currentIndex++; 
    loadImages(context, width, height, imageURLarray, currentIndex); 
    return; 
} 
+0

4年后,这个问题仍然得到意见,所以我想我提到,如果你有很多图像,你可能想用'setTimeout(...,0)'调用递归'loadImages',这样调用堆栈不会溢出。 – Braains

回答

13

后,开始工作也许这将帮助:

currentimage.onload = function(e){ 
    // code, run after image load 
} 

如果需要等待图像加载,下面的代码将加载下一个图像(CURRENTINDEX是你的“IMG”变量):

var loadImages = function(imageURLarray, currentIndex){ 
    if (imageURLarray.length == 0 || imageURLarray.length == currentIndex) return false; 
    if (typeof currentIndex == 'undefined'){ 
     currentIndex = 0; 
    } 
    // your top code 
    currentimage.onload = function(e){ 
     // code, run after image load 
     loadImages(imageURLArray, currentIndex++); 
    } 
} 

取而代之的是 “for” 循环,例如使用此功能:

loadImages(imageURLarray); 
+2

我在看这个,但我的理解是,脚本的其余部分将继续运行,直到图像加载并且该功能被触发,所以我将具有相同的竞争条件。 – Braains

+0

@Braains,如果正确实施,那么没有。如果你有另一个代码,显示 – maximkou

+1

onload不会等待加载下一张图片 –

0

也许试试这个:

http://jsfiddle.net/jnt9f/

设置IMG SRC会让之前设置onload处理确保即使图像被缓存也会触发onload事件

var $imgs = $(),i=0; 
for (var img = 0; img < imageURLarray.length; img++) { 
    $imgs = $imgs.add('<img/>'); 
} 

var fctn = (function fctn(i){ 
    $imgs.eq(i).on('load',function(){ 
     //do some stuff 
     //... 
     fctn(++i); 
    }).attr('src',imageURLarray[i]);  
})(0); 
+0

你可能会解释一下你的示例代码中发生了什么?我不像我应该那样熟悉JQuery。 – Braains

+0

这是为了避免任何竞争条件。只有在上次完全加载时,才会开始加载下一张图片。看到j​​sfiddle在更新的答案 –

+3

@downvoter请考虑评论downvote ... –

0

...其实很多开发商都指向这里来检测图像做了jQuery的事件发生后加载时..

https://github.com/desandro/imagesloaded

如果你能确定何时事件触发你的图片加载(用于例如,在图像开始加载之前在页面上添加一个Id或类),那么您应该可以将它与github上的这个插件混合。

祝你好运!

+0

尝试过,但我不只是加载一个图像,我每次通过循环加载图像。所有这些都发生在页面加载之后。 – Braains

+0

好吧,坚持我认为我找到了一些东西。现在编辑我的答案... – blackhawk

+0

预加载的问题是我正在处理大量的图像。 – Braains

相关问题