使用 jQuery 检查图像是否已加载(无错误)

IT技术 javascript jquery image dom jquery-events
2021-01-12 05:30:16

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

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

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

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

6个回答

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

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

希望这可以帮助!

你应该把.attr线.load.error线。否则,您可能会添加这些回调之前加载图像(或遇到错误),并且不会调用它们。
2021-03-18 05:30:16
.load().error()方法混乱,现在已经过时,使用.on()和使用load,并error为事件。
2021-03-20 05:30:16
似乎没有我希望的那么好。在谷歌浏览器中,当图像已经在缓存中时,它似乎有问题。它不会触发 load() 方法。:(
2021-03-27 05:30:16
@Xavi Chrome 不是最讨厌开发的浏览器,尝试为 Internet Explorer 7 或更低版本开发。除了向图像加载添加 $_GET 参数外,每次都会加载一个新图像,就像 Gromix 建议的那样。
2021-04-02 05:30:16
欧格,你说得对。Chrome 绝对是最讨厌开发的浏览器。在明亮的方面,我想我可能已经找到了解决方法:将图像源设置为“”,然后返回到原始源。我会更新我的答案。
2021-04-03 05:30:16

按此顺序检查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;
}
有趣的是,我之前正在看那个帖子,我没有意识到他们在做什么!对于 IE 来说是完整的,因为自然宽度在 IE 中没有定义。现在要去检查一下。
2021-03-22 05:30:16
返回 img.complete && typeof img.naturalWidth != 'undefined' && img.naturalWidth != 0;
2021-03-22 05:30:16
对于那些好奇的人,这几乎就是下面链接的 imagesLoaded 库所做的。所以,对于一次性使用,去吧:github.com/desandro/imagesloaded/blob/master/...
2021-03-22 05:30:16
显然,这只能在第一次可靠地工作。如果您随后更改图像的 src,至少 safari mobile 将继续报告 naturalWidth 和 complete 的第一个值。
2021-03-30 05:30:16
@vsync 您可能希望将其用作一次性检查,如果图像尚未加载,请设置“加载”事件处理程序。没有必要通过多次运行此检查来敲打 CPU。
2021-04-02 05:30:16

根据我对element的 W3C HTML 规范的img理解,您应该能够使用completenaturalHeight属性的组合来做到这一点,如下所示:

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

complete属性的规范

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

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

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

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

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

并且available定义如下:

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

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

当一个 img 元素处于部分可用状态或完全可用状态时,称为可用。

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

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

您可以在img元素的 W3C HTML 规范MDN 上阅读有关此内容的更多信息

这在带有 SVG 图像的 Firefox 中似乎不起作用,因为浏览器报告自然高度/宽度为 0。相关错误:bugzilla.mozilla.org/show_bug.cgi?id=1328124
2021-04-02 05:30:16
不起作用的是图像加载了样式“内容:网址”
2021-04-08 05:30:16

我尝试了很多不同的方法,这种方法是唯一对我有用的方法

//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/

请注意,这在技术上加载了图像的另一个副本,并使用该代理的加载事件作为图像的事件。如果 HTTP 标头不允许共享缓存的结果,这显然无法将原始图像与相同的 URL 匹配!
2021-04-02 05:30:16
我已经测试了上面有趣的读取,并且它们在少数常见浏览器上的缓存/未缓存测试之间失败。这个答案与另一个相似,但我刚刚实施和测试过,我可以确认它适用于:EdgeWin10、IE11Win8.1、Win7IE10、Win7IE9、iOS 10.2 Chrome、iOS 10.2 Safari、mac os 10.12 Chrome、mac os 10.12 Safari、mac os 10.12 Firefox、Google Pixel 7.1、三星 S5 Android 4.4。不要忘记也使用 addEventListener/removeEventListener :D
2021-04-06 05:30:16

使用imagesLoadedjavascript 库

可用于纯 Javascript 和 jQuery 插件。

特征:

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

资源

为什么要使用 imagesLoaded 插件有充分的理由:complete似乎没有明确支持属性:无法找到有关浏览器支持的可靠信息来源。complete属性似乎也没有明确的规范:HTML5 规范是唯一提到它的规范,并且在撰写本文时仍处于草稿版本中。如果您使用naturalWidth&naturalHeight仅支持 IE9+,那么如果您使用它来确定图像是否已加载,则需要一些“聪明”的技巧才能使其在旧浏览器上运行,并且您必须检查跨浏览器行为是否一致
2021-03-15 05:30:16
它似乎有很多未解决的问题,其中存在重大错误,而开发人员似乎并没有做太多的事情来追赶它们。截至目前,这在生产环境中完全无法使用。
2021-03-24 05:30:16
这对我来说非常有效。function checkImages(imgs) { $(imgs).each(function() { $(imgs).imagesLoaded() .progress(function(instance, image) { if(image.isLoaded == false) { console.log(image .img.src + '无法找到。'); image.img.src = "/templates/img/no-image.jpg"; } }); }); }
2021-03-29 05:30:16
@vsync 您是否阅读了一些未解决的问题?他几乎对所有这些都做出了回应,而且大多数似乎是其他人很少遇到的不可复制的边缘案例。我在生产中从未遇到过问题。
2021-04-06 05:30:16
是的,我自己使用它,有时它不起作用,所以我使用 setTimeout 来涵盖它失败的情况
2021-04-07 05:30:16