【问题标题】:Check if dynamically loaded images are complete检查动态加载的图像是否完整
【发布时间】:2026-01-21 08:40:02
【问题描述】:

我有一个发布到 php 脚本的代码,该脚本读取文件夹中的所有文件并返回它们,它们都是 img 的,jquery 解析信息,在一个数组的 var 上,每个图像都保存为一个 img 对象使用 src 、宽度、高度和属性,成功后我想检查每个图像是否已加载,然后最终完全触发另一个函数并删除一个 div。但我不知道如何检查图像是否已完全加载,我一直在玩弄 .complete 但它似乎永远不会加载,该函数调用 itef 直到加载 img 然后返回 true 以便它可以保持去。这是代码,有点乱,可能不是很好的编码。

var gAllImages = [];
function checkFed()

{
    var leni = gAllImages.length;   
    for (var i = 0; i < leni; i++) {


        if (!gAllImages[i].complete) {
            var percentage = i * 100.0 / (leni);
            percentage = percentage.toFixed(0).toString() + ' %';
            console.log(percentage);
            //  userMessagesController.setMessage("loading... " + percentage);
            checkFed();

            return;

        }

    //userMessagesController.setMessage(globals.defaultTitle);
    }
}


 if($('slideshow')){
 var topdiv = '<div id="loading"><div class="centered"><img src="/karlaacosta/templates/templatename/images/ajax-loader.gif" /></div> </div>';
    $('#overall').append(topdiv);
    //console.log('alerta');
    var jqxhr = $.post('http://localhost/karlaacosta/templates/templatename/php/newtest.php', function(data){



        var d = $.parseJSON(data);
        //console.log(d[1]);



        if(typeof(d) == 'object' && JSON.parse){
            var len = d.length;
            //console.log(len);



            for(var i = 0; i < len; i++){
                var theImage = new Image();
                var element = d[i].split('"');
                //        console.log(element);
                //      console.log(element[4]);
                theImage.src = '/karlaacosta/images/Fotografia/TODO'+element[0];
                theImage.width = element[2];
                theImage.height = element[4];                   
                theImage.atrr = element[6];
                gAllImages.push(theImage);

            }





        // console.log(html);
        }else{
            console.log('error');
        }
    }).success(function (){




    setTimeout('checkFed', 150);




    }).error(function(){
        var err = '<div id="error"><h2>Error: Lo sentimos al parecer no se pueden cargar las imagenes</h2></div>';
        $('#loading').append(err);

    }).complete(
        function(){
            var len = gAllImages.length;
            var html = '<ul class="slides">'    
            for(var i = 0; i < len; i++){
                html += '<li><img src="'+gAllImages[i].src+'" width="'+gAllImages[i].width+'" height="'+gAllImages[i].height+'" attr="'+gAllImages[i].attr+'" /></li>';


            }
            html += '</ul>';
            $('#slideshow').append(html);
        }
        );
 jqxhr.complete(function(){
    //
    imageSlide();
    $('#loading').remove();
    //
    console.log('completed');
});
}

如果我取出 checkFed() 的递归性,显然脚本完成了,当图像放在 html 上时,它们加载得又快又好,缓存中是否永远不会加载?也欢迎对代码的其他部分提出任何其他建议。

【问题讨论】:

  • 可以使用 img 加载回调。 *.com/questions/3877027/…
  • 我现在没有时间分析和回答这个问题,但请注意setTimeout(checkFed(), 4000); 确实安排checkFed 在四秒后运行。它立即运行checkFed,然后将其返回值传递给setTimeout。我没有看到 checkFed 返回一个函数,所以这可能是问题的一部分。如果您的目标是安排它在四秒后运行,请从 checkFed 之后删除 ()
  • 我想回答这个问题,但我现在没有时间。似乎提供的答案不会成功。

标签: image jquery


【解决方案1】:

我想检查每个图像是否已加载,然后最终完全启动另一个功能并删除一个 div。但我不知道如何检查图像是否已完全加载

从根本上说,检查图像加载是否成功很简单:

var theImage = new Image();
var element = d[i].split('"');
$(theImage).load(function() {
    // The image has loaded (from cache, or just now)
    // ...do something with the fact the image loaded...
});
theImage.src = '/karlaacosta/images/Fotografia/TODO'+element[0];

上面的关键是在你设置src之前挂钩load事件。如果你先设置src,并且图像在缓存中,load 事件可以在下一行代码钩住它之前触发,你会错过它。


这是一个例子:Live copy | source

HTML:

<img src="http://www.gravatar.com/avatar/ca3e484c121268e4c8302616b2395eb9?s=32&d=identicon&r=PG">
<p>When you see the image above, 
<input type="button" id="theButton" value="Click Me"></p>

JavaScript:

jQuery(function($) {

  $("#theButton").click(function() {
    var img = document.createElement('img');
    $(img).load(function() {
      display("Image <code>load</code> event received");
    });
    img.src = "http://www.gravatar.com/avatar/ca3e484c121268e4c8302616b2395eb9?s=32&d=identicon&r=PG";
    document.body.appendChild(img);
  });

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }
});

如您所见,我在每种情况下都使用相同的 img src。在我尝试过的每个浏览器上,我确实确实收到了load 事件。

【讨论】:

  • 但是如果没有src,它如何检查图像是否完全加载?你只是附加一个事件,然后它可以检查它是否完整?
  • @SamuelLopez:没有检查;浏览器会为您做到这一点。首先你钩住事件。然后设置src,它允许加载图像(没有src 就无法加载)。此时,如果图像在缓存中,将安排load 事件回调;但是如果你还没有钩住它,那不会是因为浏览器会查看事件处理程序链并看到没有任何处理程序被钩住。回调实际上会在 JS 引擎(在这种情况下是单线程的)空闲时执行,这将在(非常)短暂的暂停之后。
  • @SamuelLopez:添加了一个示例。
  • .load 事件在缓存后不会在某些浏览器上触发。您必须检查缓存副本。
  • @Fresheyeball:你有这方面的参考吗?以我的经验,如果你以正确的顺序做事(见上文),load 是 100% 可靠的。
【解决方案2】:

由于浏览器缓存和事件模型的怪异,它无法在没有插件的情况下以可靠的跨浏览器方式实现。试试 imagesLoaded 或 waitForImages。

https://github.com/desandro/imagesloaded

https://github.com/alexanderdickson/waitForImages

【讨论】:

  • ...如果插件可以做到,为什么本地代码不能?这就是一个插件对吗?
  • 确实如此,您始终可以对自己的系统进行正确的处理,但这些插件成熟可靠。如果您想在此处查看挑战,请查看它们的编写方式。
  • 感谢插件的链接,请检查一下,我不喜欢使用插件
  • 我正在检查那些插件,但看起来他们检查 DOM 元素是否已加载,我想检查图像是否预加载到缓存中,或者我错过了什么?我只是快速浏览了一下,稍后我会详细检查它们
  • 基本上就是这样。如果您可以在没有插件的情况下以可靠的方式复制它,并且也希望这样做,那么您将获得更多的力量。
【解决方案3】:

现在您绝对应该只检查.complete 值。示例:

var imgs = document.querySelectorAll("img");
imgs.forEach(function(e) { console.log(e.src + ":" + e.complete); });

详情见https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/complete

如果缓存标头不允许适当的缓存以允许另一个图像来自相同的 URL 用作在实际内容中加载图像的代理。请注意,即使代理检测对每个缓存都有一定的作用,但如果浏览器实现了它在实践中仍然可能失败,例如图像异步渲染。

如果用户代理不支持.complete,跟随代理对象的进度事件是最不坏的选择。但是,如果支持.complete,那么它是查询真实状态的唯一真实方式。

【讨论】: