2013-09-23 38 views
0

我有一个JavaScript使用许多图像,并且我想在用户开始点击前加载它们。图像有点大,所以需要一段时间。这里是我的代码:Javascript的 - 正在加载图像

startTest(); 

function preloadImages() { 
    console.log("preload images"); 
    for(var i = 1; i <= 132; i++) { 
     var img = new Image(); 
     images[i-1] = "images/"+i+".png"; 
     img.src = images[i-1]; 
     if(i == 132) { 
      img.load = doneLoading(); 
     } 
    } 
} 

function doneLoading() { 
    console.log("done loading"); 
    document.getElementById("laading").style.display = "none"; 
    console.log("loading gone"); 
    showReady(); 
} 

function startTest() { 
    console.log("start test"); 
    trialCount = 0; 
    document.getElementById("laading").style.display = "block"; 

    preloadImages(); 
    var hammertime = Hammer(document.body).on("touch", function(event) { 
     registerTouch(event); 
    }); 

    startTestTime = +new Date(); 
    console.log("end start test"); 
} 

正如你所看到的,startTest()首次调用,调用预先载入图像。这里的问题: 当我加载页面在浏览器中的JavaScript控制台指示"done loading"已经打印,但是spinny轮在浏览器选项卡上显示该网页仍在加载...

这是怎么回事在这?一旦我的所有图像完成加载,我怎么才能弄清楚?

+0

可能重复[加载特定图像之前其他](http://stackoverflow.com/questions/7511352/load-specific-image-before-anything-else) – Shea

+0

有一件事:你不应该认为最后你创建的图像是最后一个要完成的图像('img.load = doneLoading();'应该可以为所有图像完成,然后检查它是否被调用了132次) – fiddler

回答

3

您需要检查每个图像加载的图像是最后一个加载。使用计数变量(loaded)进行检查。

function preloadImages() { 

    var loaded = 0; 

    for(var i = 0; i <= 132; i++) { 

    var img = new Image(); 

    images.push("images/"+(i+1)+".png"); 
    img.src = images[i]; 

    img.onload = function(){ 

     loaded++; 

     if(!(loaded < 132)){ 

     // all images have loaded 
     doneLoading(); 

     } 
    } 
    } 
} 
+0

你试过这个代码吗?我把一个console.log(加载)在加载++下,它永远不会被打印......嗯。有任何想法吗? – CodeGuy

+0

哎呀,试试'onload'而不是'onLoad' ... – shennan

+0

啊,太好了,谢谢! – CodeGuy

0

为了做一个预加载,你将不得不继续检查正在下载的每个图像的complete状态。因为,您无法事先知道每个图像需要下载多少时间(取决于延迟或大小),您必须实现一个计时器,该计时器将继续轮询每个图像上的complete状态。

这里是一个可能的算法:

var timer = null, 
    numImages = 132, 
    allImages = new Array; 

function preLoadImages() { 
    document.getElementById('loadcaption').innerHTML = 'Loading images... '; 
    for (var i = 0; i < numImages; i++) { 
     var tmp = "images/" + i + ".png"; 
     allImages[i] = new Image(); 
     allImages[i].onLoad = imgOnLoad(tmp); 
     allImages[i].src = tmp; 
    } 
    timer = window.setInterval('checkLoadComplete()', 250); 
} 

function imgOnLoad(imgName) { window.status = 'Loading image... ' + imgName; } 

function checkLoadComplete() { 
    for (var i = 0; i < allImages.length; i++) { 
     if (!allImages[i].complete) { 
      imgOnLoad(allImages[i].src); 
      document.getElementById('loadcaption').innerHTML = 'Loading images... ' + Math.round((i/allImages.length)*100,0) + ' %'; 
      return; 
     } 
    } 
    window.clearInterval(timer); 
    document.getElementById('loadcaption').innerHTML = 'Completed.'; 
    window.status = ''; 
} 

loadcaption是一个简单的HTML元素以显示进度。 (您也可以使用动画GIF来加载动画)。

想法是通过定时器调用checkLoadComplete来检查每个图像上的complete状态。一旦所有图像(加载)completefor循环退出并清除定时器。

您通过调用preLoadImages();函数开始预加载过程。

+0

我觉得这可能会过度... – shennan

+0

是@shennan,对于大多数实际的目的来说,这是一个矫枉过正的行为。实际上,这是基于我之前的缓存图像出现问题的经历之一。此外,在大量图像的情况下,“完整”属性没有及时更新。因此,我的页面实际上显示预加载过早几秒钟“完成”。所以我不得不等待明确检查'complete'属性。否则,你的答案是完美的。 +1当然你的答案。 – Abhitalks

+0

够公平的。我从来没有遇到缓存图片的问题,但也许我之前没有遇到过您的用户案例。 – shennan