在 JQuery 中预加载声音和图像.它通常有效,但有时会冻结,我将不胜感激有关改进代码的建议



这是我第一次在这个网站上提出一个我越来越喜欢的问题。我正在尝试用JQuery制作游戏,我需要预加载声音和图像。如果图像和声音已经在浏览器的缓存中,它似乎每次都可以工作,但如果它们还没有在浏览器的缓存中,有时它会在加载过程中冻结,尤其是在 Firefox 上。我的问题是,是什么原因导致这种情况发生,我该如何防止它发生?刷新页面通常可以解决问题,但如果可能的话,我希望它在第一次就能完美运行。这是我的代码:

.HTML:

<div id='loading_screen'>Loading <span id='how_much_loaded'>0</span>%</div>
<div id='content'>This is the content</div>

.CSS:

#content{opacity:0}
#loading_screen{position:absolute;left:0px;top:0px}

Javascript:

var sounds=["sound0.wav","sound1.wav","sound2.wav","sound3.wav","sound4.wav","sound5.wav","sound6.wav","ding.wav"]
var images=["background-3_blue.jpg","background-3_green.jpg","background-3_yellow.jpg","background-3_red.jpg","play2train.png"]
var loaded_items=0;
var total_items=sounds.length+images.length;
function preload()
{
    for (var index=0;index<images.length;index++)
    {
        $("#preload").append(
            $("<img />").attr({
            src: images[index],
            onload: "counter();",
            style: "display:none"})
         )
    }
    for (var index=0;index<sounds.length;index++)
    {
        $("#preload").append(
            $("<audio />").attr({
            src: sounds[index],
            oncanplaythrough='counter()',
            style: "display:none"})
        )
    }
}
function counter()
{
    loaded_items++;
    $("#how_much_loaded").html((Math.round(loaded_items/total_items*100)))
    if (loaded_items==total_items)
    {
        $("#loading_screen").remove();
        $("#content").animate({"opacity":1});
    }
}

这是我正在开发的游戏。看看它是否适用于您的计算机。谢谢!!

实际上,

您不需要创建 DOM 元素并将它们附加到 DOM 中。由于您拥有资源的 URL,因此只需对它执行快速获取请求,以便您可以缓存它。

这是我不久前所做的:

    var assets = images.concat(sounds); //array of assets
    var i = 0,             //counting assets
        l = assets.length, //length of array
        w = 0;
    var enterframe = setInterval(function()                 //create an enterframe loop
    {
      w += ((100 * i / l) - w) * .8;                        //simple easing function
      document.getElementById('bar').style.width = w + '%'; //apply of value
    }, 25);
    //this function is for delaying assets loading
    function delay(callback, ms) { return function() { setTimeout(callback, ms); } }
    //kind of deferred for loop
    function load()
    {
      if (i != l) { $.get(assets[i++], delay(load, 10)); }
      else { clearInterval(enterframe); exit_preloader(); }
    };

编辑:

另外,我刚刚注意到您同时开始加载所有资产。这不是最好的方法,因为浏览器将同时启动所有请求。您至少应该使用我的代码中编写的"延迟循环"结构,以确保将每个资产加载到一个接一个,作为一个序列。

最新更新