252

我正在使用带有 jQ​​uery 库的 JavaScript 来操作包含在无序列表中的图像缩略图。加载图像时,它会做一件事,当发生错误时,它会做另一件事。我使用 jQueryload()error()方法作为事件。在这些事件之后,我检查 .complete 的图像 DOM 元素,以确保在 jQuery 注册事件之前图像尚未加载。

它可以正常工作,除非在 jQuery 注册事件之前发生错误。我能想到的唯一解决方案是使用 imgonerror属性在全局某处(或在它自身的节点上)存储一个“标志”,表示它失败,因此 jQuery 可以在检查 .complete 时检查该“存储/节点”。

有人有更好的解决方案吗?

编辑:加粗的要点并在下面添加了额外的细节: 在我在图像上添加加载和错误事件之后,我正在检查图像是否完整(也就是加载)。这样,如果在注册事件之前加载了图像,我仍然会知道。如果在事件之后没有加载图像,那么事件将在它加载时处理它。这样做的问题是,我可以轻松检查是否已经加载了图像,但我无法判断是否发生了错误。

4

15 回答 15

269

按顺序检查completenaturalWidth属性。

https://stereochro.me/ideas/detecting-broken-images-js

function IsImageOk(img) {
    // During the onload event, IE correctly identifies any images that
    // weren’t downloaded as not complete. Others should too. Gecko-based
    // browsers act like NS4 in that they report this incorrectly.
    if (!img.complete) {
        return false;
    }

    // However, they do have two very useful properties: naturalWidth and
    // naturalHeight. These give the true size of the image. If it failed
    // to load, either of these should be zero.
    if (img.naturalWidth === 0) {
        return false;
    }

    // No other way of checking: assume it’s ok.
    return true;
}
于 2009-12-30T01:05:09.600 回答
266

另一种选择是通过创建内存图像元素并将其属性设置为原始图像的原始属性来触发onload和/或事件。这是我的意思的一个例子:onerrorsrcsrc

$("<img/>")
    .on('load', function() { console.log("image loaded correctly"); })
    .on('error', function() { console.log("error loading image"); })
    .attr("src", $(originalImage).attr("src"))
;

希望这可以帮助!

于 2009-12-30T01:59:11.973 回答
70

根据我对element的 W3C HTML 规范的img理解,您应该能够使用completenaturalHeight属性的组合来执行此操作,如下所示:

function imgLoaded(imgElement) {
  return imgElement.complete && imgElement.naturalHeight !== 0;
}

complete从属性的规范:

如果以下任一条件为真,则 IDL 属性完成必须返回真:

  • src 属性被省略。
  • 获取资源后由网络任务源排队的最终任务已排队。
  • img 元素是完全可用的。
  • img 元素已损坏。

否则,该属性必须返回 false。

因此,本质上,complete如果图像已完成加载或加载失败,则返回 true。由于我们只需要成功加载图像的情况,我们还需要检查nauturalHeight属性:

IDL 属性必须返回图像的固有宽度naturalWidthnaturalHeight高度,以 CSS 像素为单位,如果图像可用,否则为 0。

并且available定义如下:

img 始终处于以下状态之一:

  • 不可用- 用户代理尚未获得任何图像数据。
  • 部分可用- 用户代理已获得部分图像数据。
  • 完全可用- 用户代理已获得所有图像数据,并且至少图像尺寸可用。
  • Broken - 用户代理已经获得了它可以获取的所有图像数据,但它甚至无法对图像进行足够的解码以获取图像尺寸(例如图像损坏,或不支持格式,或无法获得数据) .

当一个 img 元素处于部分可用状态或完全可用状态时,就说它是可用的。

因此,如果图像“损坏”(无法加载),那么它将处于损坏状态,而不是可用状态,因此naturalHeight将为 0。

因此,检查imgElement.complete && imgElement.naturalHeight !== 0应该告诉我们图像是否已成功加载。

您可以在该元素的 W3C HTML 规范imgMDN 上阅读更多相关信息。

于 2016-01-11T16:49:19.413 回答
25

我尝试了许多不同的方法,这种方法是唯一适合我的方法

//check all images on the page
$('img').each(function(){
    var img = new Image();
    img.onload = function() {
        console.log($(this).attr('src') + ' - done!');
    }
    img.src = $(this).attr('src');
});

您还可以添加一个回调函数,在所有图像都加载到 DOM 并准备就绪后触发。这也适用于动态添加的图像。http://jsfiddle.net/kalmarsh80/nrAPk/

于 2013-07-31T01:15:01.577 回答
14

使用imagesLoadedjavascript 库

可用于纯 Javascript 和作为 jQuery 插件。

特征:

  • IE8+官方支持
  • 执照:麻省理工学院
  • 依赖:无
  • 重量(缩小和压缩):7kb 缩小(轻!)

资源

于 2013-11-13T16:58:19.770 回答
10

从页面上的图像元素中检索信息
测试在 Chrome 和 Firefox 上
工作jsFiddle(打开控制台查看结果)

$('img').each(function(){ // selecting all image element on the page

    var img = new Image($(this)); // creating image element

    img.onload = function() { // trigger if the image was loaded
        console.log($(this).attr('src') + ' - done!');
    }

    img.onerror = function() { // trigger if the image wasn't loaded
        console.log($(this).attr('src') + ' - error!');
    }

    img.onAbort = function() { // trigger if the image load was abort
        console.log($(this).attr('src') + ' - abort!');
    }

    img.src = $(this).attr('src'); // pass src to image object

    // log image attributes
    console.log(img.src);
    console.log(img.width);
    console.log(img.height);
    console.log(img.complete);

});

注意:我使用了jQuery,我认为这可以在完整的 javascript 上实现

我在这里找到了很好的信息OpenClassRoom --> 这是一个法语论坛

于 2016-04-20T00:52:27.547 回答
4

在阅读了此页面上有趣的解决方案后,我创建了一个易于使用的解决方案,该解决方案深受 SLaks 和 Noyo 的帖子的影响,该解决方案似乎适用于 Chrome、IE、Firefox、Safari 和Opera(全部在 Windows 上)。此外,它还可以在我使用的 iPhone/iPad 模拟器上运行。

此解决方案与 SLaks 和 Noyo 的帖子之间的一个主要区别是此解决方案主要检查 naturalWidth 和 naturalHeight 属性。我发现在当前的浏览器版本中,这两个属性似乎提供了最有用和最一致的结果。

当图像完全加载且成功时,此代码返回 TRUE。当图像尚未完全加载或加载失败时,它返回 FALSE。

您需要注意的一件事是,如果图像是 0x0 像素图像,此函数也将返回 FALSE。但是这些图像很少见,我想不出一个非常有用的情况,您想检查是否已加载 0x0 像素图像:)

首先,我们将一个名为“isLoaded”的新函数附加到 HTMLImageElement 原型,以便可以在任何图像元素上使用该函数。

HTMLImageElement.prototype.isLoaded = function() {

    // See if "naturalWidth" and "naturalHeight" properties are available.
    if (typeof this.naturalWidth == 'number' && typeof this.naturalHeight == 'number')
        return !(this.naturalWidth == 0 && this.naturalHeight == 0);

    // See if "complete" property is available.
    else if (typeof this.complete == 'boolean')
        return this.complete;

    // Fallback behavior: return TRUE.
    else
        return true;

};

然后,每当我们需要检查图像的加载状态时,我们只需调用“isLoaded”函数即可。

if (someImgElement.isLoaded()) {
    // YAY! The image loaded
}
else {
    // Image has not loaded yet
}

根据 giorgian 对 SLaks 和 Noyo 帖子的评论,如果您打算更改 SRC 属性,此解决方案可能只能用作 Safari Mobile 的一次性检查。但是您可以通过创建具有新 SRC 属性的图像元素来解决此问题,而不是更改现有图像元素上的 SRC 属性。

于 2015-07-28T17:53:58.810 回答
3

实时网络检测器 - 在不刷新页面 的情况下检查网络状态:(它不是 jquery,但经过测试,并且 100% 有效:(在 Firefox v25.0 上测试))

代码:

<script>
 function ImgLoad(myobj){
   var randomNum = Math.round(Math.random() * 10000);
   var oImg=new Image;
   oImg.src="YOUR_IMAGELINK"+"?rand="+randomNum;
   oImg.onload=function(){alert('Image succesfully loaded!')}
   oImg.onerror=function(){alert('No network connection or image is not available.')}
}
window.onload=ImgLoad();
</script>

<button id="reloadbtn" onclick="ImgLoad();">Again!</button>

如果连接丢失,只需按再次按钮。

更新1: 自动检测而不刷新页面:

<script>
     function ImgLoad(myobj){
       var randomNum = Math.round(Math.random() * 10000);
       var oImg=new Image;
       oImg.src="YOUR_IMAGELINK"+"?rand="+randomNum;
       oImg.onload=function(){networkstatus_div.innerHTML="";}
       oImg.onerror=function(){networkstatus_div.innerHTML="Service is not available. Please check your Internet connection!";}
}

networkchecker = window.setInterval(function(){window.onload=ImgLoad()},1000);
</script>

<div id="networkstatus_div"></div>
于 2013-10-16T14:46:25.613 回答
2

这就是我使用上述方法的组合使其跨浏览器工作的方式(我还需要将图像动态插入到 dom 中):

$('#domTarget').html('<img src="" />');

var url = '/some/image/path.png';

$('#domTarget img').load(function(){}).attr('src', url).error(function() {
    if ( isIE ) {
       var thisImg = this;
       setTimeout(function() {
          if ( ! thisImg.complete ) {
             $(thisImg).attr('src', '/web/css/img/picture-broken-url.png');
          }
       },250);
    } else {
       $(this).attr('src', '/web/css/img/picture-broken-url.png');
    }
});

注意:您需要为 isIE 变量提供有效的布尔状态。

于 2013-03-30T19:01:09.043 回答
2
var isImgLoaded = function(imgSelector){
  return $(imgSelector).prop("complete") && $(imgSelector).prop("naturalWidth") !== 0;
}

// 或作为插件

    $.fn.extend({
      isLoaded: function(){
        return this.prop("complete") && this.prop("naturalWidth") !== 0;
      }
    })

// $(".myImage").isLoaded() 
于 2018-03-25T08:09:49.847 回答
1

据我了解 .complete 属性是非标准的。它可能不是通用的......我注意到它在 Firefox 和 IE 中的工作方式似乎不同。我在 javascript 中加载了一些图像,然后检查是否完成。在 Firefox 中,这似乎工作得很好。在 IE 中,这不是因为图像似乎正在另一个线程上加载。仅当我在分配给 image.src 和检查 image.complete 属性之间延迟时,它才有效。

使用 image.onload 和 image.onerror 对我也不起作用,因为我需要传递一个参数来知道在调用函数时我正在谈论的图像。任何这样做的方式似乎都失败了,因为它实际上似乎传递了相同的函数,而不是同一函数的不同实例。因此,我传递给它以识别图像的值总是最终成为循环中的最后一个值。我想不出任何办法来解决这个问题。

在 Safari 和 Chrome 上,即使错误控制台显示该图像的 404,我也会看到 image.complete 为 true 和 naturalWidth 设置......我故意删除了该图像来测试这一点。但上述方法适用于 Firefox 和 IE。

于 2011-10-28T15:31:53.397 回答
1

这段代码帮助我解决了浏览器缓存问题:

$("#my_image").on('load', function() {

    console.log("image loaded correctly"); 
}).each(function() {

     if($(this).prop('complete')) $(this).load();
});

当浏览器缓存被禁用时,只有这段代码不起作用:

$("#my_image").on('load', function() {
     console.log("image loaded correctly"); 
})

要使其工作,您必须添加:

.each(function() {
     if($(this).prop('complete')) $(this).load();
});
于 2017-12-15T12:52:05.007 回答
0

使用此JavaScript代码,您可以检查图像是否成功加载。

document.onready = function(e) {
        var imageobj = new Image();
        imageobj.src = document.getElementById('img-id').src;
        if(!imageobj.complete){ 
            alert(imageobj.src+"  -  Not Found");
        }
}

试试这个

于 2015-12-04T11:53:43.153 回答
0

我在完整加载图像和 EventListener 时遇到了很多问题。

无论我尝试什么,结果都不可靠。

但后来我找到了解决方案。从技术上讲,这不是一个好的,但现在我从来没有遇到过图像加载失败。

我做了什么:

                    document.getElementById(currentImgID).addEventListener("load", loadListener1);
                    document.getElementById(currentImgID).addEventListener("load", loadListener2);

                function loadListener1()
                    {
                    // Load again
                    }

                function loadListener2()
                {
                    var btn = document.getElementById("addForm_WithImage"); btn.disabled = false;
                    alert("Image loaded");
                }

我不是一次加载图像,而是在第一次之后直接加载第二次,并且都通过事件处理程序运行。

我所有的头痛都消失了!


顺便说一句:你们来自stackoverflow的帮助我已经超过一百次了。为此非常感谢!

于 2017-02-27T06:36:27.470 回答
0

这个对我来说很好:)

$('.progress-image').each(function(){
    var img = new Image();
    img.onload = function() {
        let imgSrc = $(this).attr('src');
        $('.progress-image').each(function(){
            if($(this).attr('src') == imgSrc){
                console.log($(this).parent().closest('.real-pack').parent().find('.shimmer').fadeOut())
            }
        })
    }
    img.src = $(this).attr('src');
});
于 2019-07-27T09:52:02.267 回答