使用jQuery检查是否加载了图像(没有错误)

Wil*_*iam 215 javascript jquery dom image jquery-events

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

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

谁有更好的解决方案?

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

Xav*_*avi 240

另一种选择是通过创建内存图像元素并将其属性设置为原始图像的原始属性来触发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"))
;
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

  • 似乎没有像我希望的那样好用.在谷歌浏览器中,当图像已经在缓存中时似乎存在问题.它不会触发load()方法.:( (26认同)
  • @Xavi Chrome并不是最烦人的浏览器,尝试开发适用于Internet Explorer 7或更低版​​本的浏览器.除了向图像加载添加$ _GET参数外,每次都会加载一个新图像,就像Gromix建议的那样. (18认同)
  • `.load()`和`.error()`方法令人困惑,现在已弃用,使用`.on()`并使用`load`和`error`作为事件. (9认同)
  • 乌格,你是对的.Chrome绝对是最烦人的浏览器.在明亮的情况下,我想我可能已经找到了解决办法:将图像源设置为""然后再回到原始源.我会更新我的答案. (4认同)
  • 下面的答案更好。检查“complete”和“naturalWidth”,否则您只是将额外的带宽用于不需要的内容 (2认同)

SLa*_*aks 223

按顺序检查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;
}
Run Code Online (Sandbox Code Playgroud)

  • return img.complete && typeof img.naturalWidth!='undefined'&& img.naturalWidth!= 0; (5认同)
  • @vsync您可能希望将其用作一次性检查,如果图像尚未加载,请设置"加载"事件处理程序.通过多次运行此检查,不需要锤击CPU. (5认同)
  • 显然,这只是第一次可靠地工作.如果您随后更改了图像的src,至少safari mobile将继续报告naturalWidth和complete的第一个值. (3认同)
  • 对于那些好奇的人来说,这几乎就是下面链接的imagesLoaded库的功能。因此,一次使用就可以了:https://github.com/desandro/imagesloaded/blob/master/imagesloaded.js#L284-L288 (2认同)

Aje*_*i32 52

基于我对元素的W3C HTML规范的img理解,你应该能够使用completenaturalHeight属性的组合来做到这一点,如下所示:

function imgLoaded(imgElement) {
  return imgElement.complete && imgElement.naturalHeight !== 0;
}
Run Code Online (Sandbox Code Playgroud)

complete属性的规范:

如果满足以下任一条件,则IDL属性complete必须返回true:

  • src属性被省略.
  • 一旦获取资源,网络任务源排队的最终任务已排队.
  • img元素完全可用.
  • img元素被破坏了.

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

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

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

并且available定义如下:

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

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

当img元素处于部分可用状态或处于完全可用状态时,它被认为是可用的.

因此,如果图像被"破坏"(无法加载),那么它将处于断开状态,而不是可用状态,因此naturalHeight将为0.

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

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

  • 这似乎不适用于带有 SVG 图像的 Firefox,因为浏览器报告自然高度/宽度为 0。相关错误:https://bugzilla.mozilla.org/show_bug.cgi?id=1328124 (2认同)

Kal*_*Kal 19

我尝试了很多不同的方式,这种方式是唯一一个适合我的方式

//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');
});
Run Code Online (Sandbox Code Playgroud)

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


Jos*_*son 12

使用imagesLoadedjavascript库.

可以使用普通的Javascript和jQuery插件.

特征:

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

资源

  • @vsync您是否阅读了一些未解决的问题?他对几乎所有人都做出了回应,而且大多数似乎都是不可复制的边缘案例,很少有人会遇到这种情况.我从来没有在生产中遇到过问题. (3认同)
  • 它似乎有大量未解决的问题,这些问题是主要的错误,而开发人员似乎没有做太多的工作来赶上它们。到目前为止,这在生产环境中完全无法使用。 (2认同)

Jul*_*lha 8

检索上的页面图像元素的信息
在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);

});
Run Code Online (Sandbox Code Playgroud)

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

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


小智 5

在阅读了本页上有趣的解决方案后,我创建了一个易于使用的解决方案,该解决方案深受 SLaks 和 Noyo 的帖子影响,该解决方案似乎适用于 Chrome、IE、Firefox、Safari 和 Chrome 的最新版本(截至撰写时) 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;

};
Run Code Online (Sandbox Code Playgroud)

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

if (someImgElement.isLoaded()) {
    // YAY! The image loaded
}
else {
    // Image has not loaded yet
}
Run Code Online (Sandbox Code Playgroud)

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