【问题标题】:Preloading Images & [object HTMLImageElement]预加载图像和 [object HTMLImageElement]
【发布时间】:2013-02-18 19:06:05
【问题描述】:

我正在尝试创建预加载器,但是当我运行它时,控制台会显示:

已加载 [object HTMLImageElement],共 5 个

从这行代码

console.log('Loaded ' + images[i] + ' of ' + images.length);

但理想情况下我希望它显示:

“已加载 1 个,共 5 个”

我该如何解决这个问题?我只想将其创建为回调,以便知道某个面板中的所有图像何时加载。

$(panel).each(function(){

    // Find Panel
        var panelId = $(this).attr('id');
        console.log('Loading ' + panelId);  

    // Find Images
        var images = $(this).find('img');
        var path = images.attr('src');
        console.log('Total of ' + images.length + ' Images');

    // Preload Images
        for( i= 0; i < images.length; i++ ) {

            images[i] = new Image();
            images[i].src = path;
            images[i].onload = function(){
                console.log('Loaded ' + images[i] + ' of ' + images.length);
            };

        }

    // End

});

另外 - 我如何修改我的 each() 循环,在前一个面板完成检查后检查每个面板?

任何帮助都会很棒。谢谢。

【问题讨论】:

  • @ÁlvaroG.Vicario 来自 for 循环?我认为需要从循环中拉出 [i] 变量?
  • 对不起,我看错了你的问题,我会删除我的评论。
  • 无论如何您都不能真正使用i,因为不能保证图像加载的顺序。如果你使用i,你可能会得到1,3,2,4,5,具体取决于每张图片的大小。此外,在您上面的代码中,您总是得到相同的images[i],即最后一个。
  • @KevinB 有道理,只要我知道加载了哪些顺序,我就不会太在意它加载它们的顺序。

标签: jquery image preload


【解决方案1】:

只需声明一个计数器并随时递增:

$(panel).each(function(){
        var loaded = 0; // <== The counter

    // Find Panel
        var panelId = $(this).attr('id');
        console.log('Loading ' + panelId);  

    // Find Images
        var images = $(this).find('img');
        var path = images.attr('src');
        console.log('Total of ' + images.length + ' Images');

    // Preload Images
        for( i= 0; i < images.length; i++ ) {

            images[i] = new Image();
            images[i].src = path;
            images[i].onload = function(){
                ++loaded;
                console.log('Loaded ' + loaded + ' of ' + images.length);
            };

        }

    // End

});

不要使用i,正如至少一位评论者所建议的那样(正如我在更仔细阅读您的代码之前所建议的那样)。在加载回调完成时,i 将始终为 images.length

您需要进行的另一项更改是设置onload 回调before 设置src,因此:

// PROBLEM, sets up a race condition
images[i].src = path;
images[i].onload = function(){
    // ...
};

这样做:

images[i].onload = function(){
    // ...
};
images[i].src = path;

网络浏览器上的 JavaScript 是单线程的(除非使用网络工作者),但 网络浏览器不是。它可以轻松地检查其缓存并查看它是否具有图像并运行其代码以触发行设置src 和行设置onload 之间的load 处理程序。它将排队处理程序以便在下次 JavaScript 引擎可用时运行,但如果您的处理程序不在那里排队,它将不会排队,并且您永远不会收到 load 事件回调。

【讨论】:

  • 这有效,但不在 panel.each 循环内。它继续计数器到下一个面板 Loaded 1 of 5 Loaded 2 of 5 Loaded 3 of 5 Loaded 4 of 5 Loaded 5 of 5 Loaded 6 of 1
  • @JasonMayo:抱歉,误读了图片的来源。您只需将var loaded = 0;移入迭代回调(答案已更新)。
  • @t-j-crowder 邪恶的,这行得通。你说的都是有道理的。知道如何为我的面板制作每个循环,在前一个面板中加载所有图像后加载下一个面板吗?这个解决方案是为了克服我在你之前回答的问题中遇到的问题。我决定不从外部文件加载内容。
  • @JasonMayo:这基本上是我之前向您展示的机制。不要执行each 循环,而是为您正在加载的面板设置一个索引,然后调用您的函数来加载面板并等待其图像。一旦loaded 等于images.length,增加面板索引并(如果您还有其他面板)再次调用函数本身。
  • @t-j-crowder 明白了!现在会大吃一惊。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
  • 1970-01-01
  • 1970-01-01
  • 2013-09-08
  • 1970-01-01
  • 2011-10-26
  • 2010-11-25
相关资源
最近更新 更多