2012-04-01 35 views
4

我编写了一个脚本,用户在其中选择一个数据范围,然后从服务器获取一串图像(超过150个),然后循环通过它们来制作类似电影。我想知道的是在移动图像时加载防止延迟的最有效方法。在html上快速加载很多图像

目前,我正在使用Ajax从服务器获取图像,并将它们存储在JavaScript的Image对象数组中。在HTML中,我有一个div标签,我希望放置图像。我创建完所有图像对象(并设置其适当SRC)数组中后,我做到以下几点:

imgElem = document.createElement('img'); 
document.getElementById('loopLocation').appendChild(imgElem); 
imgElem.src = images[0].src; 

此后,我只是做了最近一个电话,但改变环路指数。我每400ms就这样做一次。该循环有效,但有时会滞后,并会在图像上冻结更长的时间。我想知道如果我能够从客户端改进这一点,或者我只需要一个响应速度更快的服务器。

+0

嗯,如何在预先加载所有图像之前开始在循环中显示它们?或者出于某种原因,这不是一种选择? – Raine 2012-04-01 07:11:22

+0

在显示它们之前,我确实将它们放在了阵列上。 – Sednus 2012-04-01 07:14:38

+1

是的,看到我在下面发布的链接,有一种方法可以在所有图片已经成功加载到浏览器缓存中的情况下运行脚本,这将允许循环避免加载它们“即时” – Raine 2012-04-01 07:18:52

回答

6

你可能想考虑spriting这是把所有的图像放在一个大的图像。有了这个,你只需要加载一个大的图像,然后重新定位每个场景。

或者,在实际使用它们之前,您可能还需要预先加载这150个图像。你可以使用JS数组来存储Image对象,然后遍历该数组来获取图像。

var images = []; 
var expectLoaded = 150; 

for(var i = 0; i<expectLoaded;i++){ 
    (function(i){ 

     //new image object 
     var img = new Image(); 

     //onload hander 
     img.onload = function(){ 

      //after load, push it into the array 
      images.push[img]; 

      //and check if the all has loaded 
      if(images.length === expectLoaded){ 
       //preload done 
      } 
     } 

     //start loading this image 
     img.src = //path to image[i]; 

    },(i)); 
} 

循环阻塞UI线程。 JS是单线程的,意味着代码以线性方式依次执行。在循环语句之后的任何内容都会等到循环结束。如果这个循环需要很长时间......请喝点咖啡。此外,由于您正在操作DOM,因此UI线程被阻止后,您看不到更改。

但有一些方法可以绕过这一点,其中一个使用超时来延迟和排队代码,以便稍后执行,当JS不忙时。

function animate(frameNo){ 

    //animate frame[frameNo]; 

    if(frameNo < total_frames){ //make the UI breate in between frames 
     setTimeout(function(){ //so that changes reflect on the screen 
      animate(++frameNo); //then animate next frame 
     },200);     
    } 
} 

//start 
animate(0); 
+1

一样。 – Sednus 2012-04-01 07:15:31

+1

所以你有图像,问题是帧率? – Joseph 2012-04-01 07:19:51

+1

嗯,有点像spritesheet – 2012-04-01 07:20:35