使用jQuery检查是否加载了图像(没有错误)
我正在使用JavaScript与jQuery库来操作无序列表中包含的图像缩略图。 当图像被加载时,它会做一件事,当发生错误时它会做其他事情。 我正在使用jQuery load()和error()方法作为事件。 在这些事件之后,我检查.complete的图像DOM元素,以确保在jQuery注册事件之前图像尚未加载。
它正常工作,除非在jQuery注册事件之前发生错误。 我能想到的唯一解决方案是使用img onerror属性在全局某个地方(或在它自己的节点上)存储一个“标志”,表示它失败了,因此jQuery可以在检查.complete时检查“存储/节点”。
谁有更好的解决方案?
编辑:粗体主要点并在下面添加额外的细节:我正在检查图像是否完整(也称为加载)我在图像上添加加载和错误事件后。 这样, 如果在事件被注册之前加载了图像,我仍然会知道。 如果在事件之后未加载图像,则事件将在事件发生时进行处理。 这个问题是,我可以很容易地检查是否已经加载了图像,但我无法判断是否发生了错误。
另一种选择是通过创建内存映像元素并将其src
属性设置为原始映像的原始src
属性来触发onload
和/或onerror
事件。 这是我的意思的一个例子:
$("") .on('load', function() { console.log("image loaded correctly"); }) .on('error', function() { console.log("error loading image"); }) .attr("src", $(originalImage).attr("src")) ;
希望这可以帮助!
按顺序检查complete
和naturalWidth
属性。
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; }
根据我对img
元素的W3C HTML规范的理解,您应该能够使用complete
和naturalHeight
属性的组合来完成此操作,如下所示:
function imgLoaded(imgElement) { return imgElement.complete && imgElement.naturalHeight !== 0; }
从complete
属性的规范:
如果满足以下任一条件,则IDL属性complete必须返回true:
- src属性被省略。
- 一旦获取资源,网络任务源排队的最终任务已排队。
- img元素完全可用。
- img元素被破坏了。
否则,该属性必须返回false。
基本上,如果图像已完成加载或加载失败,则complete
返回true。 由于我们只想要成功加载图像的情况,我们还需要检查nauturalHeight
属性:
IDL属性
naturalWidth
和naturalHeight
必须返回图像的固有宽度和高度,如果图像可用,则返回CSS像素,否则返回0。
available
的定义如下:
img始终处于以下状态之一:
- 不可用 – 用户代理尚未获取任何图像数据。
- 部分可用 – 用户代理已获取一些图像数据。
- 完全可用 – 用户代理已获取所有图像数据,并且至少可以使用图像尺寸。
- 破碎 – 用户代理已经获得了它可以获得的所有图像数据,但它甚至无法解码图像以获得图像尺寸(例如图像已损坏,或者格式不受支持,或者无法获得数据) 。
当img元素处于部分可用状态或处于完全可用状态时,它被认为是可用的。
因此,如果图像被“破坏”(无法加载),那么它将处于断开状态,而不是可用状态,因此naturalHeight
将为0。
因此,检查imgElement.complete && imgElement.naturalHeight !== 0
应该告诉我们图像是否已成功加载。
您可以在img
元素的W3C HTML规范中或在MDN上阅读有关此内容的更多信息。
我尝试了很多不同的方式,这种方式是唯一一个适合我的方式
//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/
使用imagesLoaded
javascript库 。
可以使用普通的Javascript和jQuery插件。
特征:
- IE8 +正式支持
- 执照:麻省理工学院
- 依赖:没有
- 重量(缩小和压缩):7kb缩小(轻!)
资源
- github项目: https : //github.com/desandro/imagesloaded
- 官方网站: http : //imagesloaded.desandro.com/
- https://stackoverflow.com/questions/26927575/why-use-imagesloaded-javascript-library-versus-jquerys-window-load
- imagesloaded javascript库:什么是浏览器和设备支持?
实时网络检测器 – 检查网络状态而不刷新页面:(它不是jquery,但经过测试,100%有效:(在Firefox v25.0上测试过))
码:
如果连接丢失,只需按“再次”按钮。
更新1:自动检测而不刷新页面:
从页面上的图像元素中检索信息
测试适用于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 – >这是一个法国论坛
这就是我使用上述方法组合使用跨浏览器工作的方式(我还需要动态地将图像插入到dom中):
$('#domTarget').html(''); 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变量提供有效的布尔状态。
在阅读了本页有趣的解决方案后,我创建了一个易于使用的解决方案,受到SLaks和Noyo的post的影响,该post似乎正在开发Chrome,IE,Firefox,Safari和最新版本(撰写时) Opera(全部在Windows上)。 此外,它适用于我使用的iPhone / iPad模拟器。
这个解决方案与Noaks和Noyo的post之间的一个主要区别是这个解决方案主要检查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的post的评论,如果您计划更改SRC属性,此解决方案可能只能用作Safari Mobile的一次性检查。 但是,您可以通过使用新的SRC属性创建图像元素而不是更改现有图像元素上的SRC属性来解决此问题。
据我所知,.complete属性是非标准的。 它可能不是通用的……我注意到它在IE和IE中的工作方式似乎有所不同。 我在javascript中加载了一些图像,然后检查是否完成。 在Firefox中,这似乎很有效。 在IE中,它不是因为图像似乎是在另一个线程上加载。 它只有在我对image.src的赋值和我检查image.complete属性之间设置延迟时才有效。
使用image.onload和image.onerror对我来说也不起作用,因为我需要传递一个参数来知道在调用函数时我正在谈论的是哪个图像。 任何这样做的方式似乎都失败了,因为它实际上似乎传递了相同的函数,而不是相同函数的不同实例。 因此,我传入其中以识别图像的值总是最终成为循环中的最后一个值。 我无法想到解决这个问题的方法。
在Safari和Chrome上,即使错误控制台显示该图像的404,我也会看到image.complete为true并设置为naturalWidth …我故意删除该图像以进行测试。 但以上适用于Firefox和IE。
使用此JavaScript
代码,您可以检查图像是否成功加载。
document.onready = function(e) { var imageobj = new Image(); imageobj.src = document.getElementById('img-id').src; if(!imageobj.complete){ alert(imageobj.src+" - Not Found"); } }
试试吧
完全加载图像和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的人已经帮助了我一百多次了。 对于这个非常大的谢谢!
这段代码帮我修复了浏览器缓存问题:
$("#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(); });
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()