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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1977871/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 22:12:28  来源:igfitidea点击:

Check if an image is loaded (no errors) with jQuery

javascriptjqueryimagedomjquery-events

提问by William

I'm using JavaScript with the jQuery library to manipulate image thumbnails contained in a unordered list. When the image is loaded it does one thing, when an error occurs it does something else. I'm using jQuery load()and error()methods as events. After these events I check the image DOM element for the .complete to make sure the image wasn't already loaded before jQuery could register the events.

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

It works correctly except when an error occurs before jQuery can register the events.The only solution I can think of is to use the img onerrorattribute to store a "flag" somewhere globally (or on the node it's self) that says it failed so jQuery can check that "store/node" when checking .complete.

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

Anyone have a better solution?

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

Edit: Bolded main points and added extra detail below:I'm checking if an image is complete (aka loaded) AFTER I add a load and error event on the image. That way, if the image was loaded before the events were registered, I will still know.If the image isn't loaded after the events then the events will take care of it when it does. The problem with this is, I can easily check if an image is loaded already, but I can't tell if an error occurred instead.

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

回答by Xavi

Another option is to trigger the onloadand/or onerrorevents by creating an in memory image element and setting its srcattribute to the original srcattribute of the original image. Here's an example of what I mean:

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

Hope this helps!

希望这可以帮助!

回答by SLaks

Check the completeand naturalWidthproperties, in that order.

按此顺序检查completenaturalWidth属性。

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

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;
}

回答by Ajedi32

Based on my understanding of the W3C HTML Specification for the imgelement, you should be able to do this using a combination of the completeand naturalHeightattributes, like so:

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

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

From the spec for the completeattribute:

complete属性的规范:

The IDL attribute complete must return true if any of the following conditions is true:

  • The src attribute is omitted.
  • The final task that is queued by the networking task source once the resource has been fetched has been queued.
  • The img element is completely available.
  • The img element is broken.

Otherwise, the attribute must return false.

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

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

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

So essentially, completereturns true if the image has either finished loading, or failed to load. Since we want only the case where the image successfully loaded we need to check the nauturalHeightattribute as well:

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

The IDL attributes naturalWidthand naturalHeightmust return the intrinsic width and height of the image, in CSS pixels, if the image is available, or else 0.

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

And availableis defined like so:

并且available定义如下:

An img is always in one of the following states:

  • Unavailable- The user agent hasn't obtained any image data.
  • Partially available- The user agent has obtained some of the image data.
  • Completely available- The user agent has obtained all of the image data and at least the image dimensions are available.
  • Broken- The user agent has obtained all of the image data that it can, but it cannot even decode the image enough to get the image dimensions (e.g. the image is corrupted, or the format is not supported, or no data could be obtained).

When an img element is either in the partially available state or in the completely available state, it is said to be available.

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

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

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

So if the image is "broken" (failed to load), then it will be in the broken state, not the available state, so naturalHeightwill be 0.

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

Therefore, checking imgElement.complete && imgElement.naturalHeight !== 0should tell us whether the image has successfully loaded.

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

You can read more about this in the W3C HTML Specification for the imgelement, or on MDN.

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

回答by Kal

I tried many different ways and this way is the only one worked for me

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

//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');
});

You could also add a callback function triggered once all images are loaded in the DOM and ready. This applies for dynamically added images too. http://jsfiddle.net/kalmarsh80/nrAPk/

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

回答by Josh Harrison

回答by Julha

Retrieve informations from image elements on the page
Test working on Chrome and Firefox
Working jsFiddle(open your console to see the result)

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

});

Note : I used jQuery, I thought this can be acheive on full javascript

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

I find good information here OpenClassRoom--> this is a French forum

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

回答by data-dan

After reading the interesting solutions on this page, I created an easy-to-use solution highly influenced by SLaks' and Noyo's post that seems to be working on pretty recent versions (as of writing) of Chrome, IE, Firefox, Safari, and Opera (all on Windows). Also, it worked on an iPhone/iPad emulator I used.

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

One major difference between this solution and SLaks and Noyo's post is that this solution mainly checks the naturalWidth and naturalHeight properties. I've found that in the current browser versions, those two properties seem to provide the most helpful and consistent results.

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

This code returns TRUE when an image has loaded fully AND successfully. It returns FALSE when an image either has not loaded fully yet OR has failed to load.

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

One thing you will need to be aware of is that this function will also return FALSE if the image is a 0x0 pixel image. But those images are quite uncommon, and I can't think of a very useful case where you would want to check to see if a 0x0 pixel image has loaded yet :)

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

First we attach a new function called "isLoaded" to the HTMLImageElement prototype, so that the function can be used on any image element.

首先,我们将一个名为“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;

};

Then, any time we need to check the loading status of the image, we just call the "isLoaded" function.

然后,任何时候我们需要检查图像的加载状态,我们只需调用“isLoaded”函数。

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

Per giorgian's comment on SLaks' and Noyo's post, this solution probably can only be used as a one-time check on Safari Mobile if you plan on changing the SRC attribute. But you can work around that by creating an image element with a new SRC attribute instead of changing the SRC attribute on an existing image element.

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

回答by Jenei Tamás

Realtime network detector - check network status without refreshing the page:(it's not jquery, but tested, and 100% works:(tested on Firefox v25.0))

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

Code:

代码:

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

if connection lost just press the Again button.

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

Update 1:Auto detect without refreshing the page:

更新 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>

回答by Justin Vincent

This is how I got it to work cross browser using a combination of the methods above (I also needed to insert images dynamically into the dom):

这就是我使用上述方法的组合使其跨浏览器工作的方式(我还需要将图像动态插入到 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');
    }
});

Note: You will need to supply a valid boolean state for the isIE variable.

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

回答by KhaledDev

var isImgLoaded = function(imgSelector){
  return $(imgSelector).prop("complete") && $(imgSelector).prop("naturalWidth") !== 0;
}

// Or As a Plugin

// 或者作为插件

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

// $(".myImage").isLoaded()