如何判断图像是否已正确加载

发布于 2024-09-24 19:39:56 字数 561 浏览 6 评论 0原文

有没有办法在事后判断图像(使用 标签放置,而不是通过 JS)是否已正确加载到页面中?我有一个头像库,有时第三方图像服务器最终会提供 404。我可以更改服务器端代码以使用 onerror="showGenericHeadshot()",但是我真的想避免更改服务器端代码。最终,我想确定图像是否丢失或损坏,并将其替换为通用的“图像未找到”图形。我尝试过的事情:

  1. Image.prototype.onerror = showGenericHeadshot - 不适用于 标签
  2. $('img[src*= thirdpartyserver.com]).error(showGenericHeadshot) -- 在 IE 中不起作用
  3. $('img[src*=thirdpartyserver.com]).css('backgroundImage','url(replacementimage. gif)') -- 有效,但仍然无法消除 IE 中损坏的图像图标

Is there a way to tell, after the fact, whether an image (placed with the <img> tag, not via JS) has loaded correctly into a page? I have a gallery of head shots, and occasionally the third-party image server ends up serving up a 404. I can change the server-side code to use an onerror="showGenericHeadshot()", but I really want to avoid making changes to server-side code. Ultimately, I want to determine if an image is missing or broken and replace it with a generic "Image Not Found" graphic. Things I've tried:

  1. Image.prototype.onerror = showGenericHeadshot -- doesn't work for <img> tags
  2. $('img[src*=thirdpartyserver.com]).error(showGenericHeadshot) -- doesn't work in IE
  3. $('img[src*=thirdpartyserver.com]).css('backgroundImage','url(replacementimage.gif)') -- works, but still doesn't get rid of the broken image icon in IE

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浅沫记忆 2024-10-01 19:39:56
<img scr='someUrl' id="testImage" />

jQuery('#testImage').bind('load',function(){
         alert ('iamge loaded');
});

为了避免竞争情况,请执行以下操作

<img _src="http://www.caregiving.org/intcaregiving/flags/UK.gif" />
// i have added an underscore character before src



jQuery('img').each(function(){
        var _elm=jQuery(this);
        _elm.bind('load',_imageLoaded).attr('src',_elm.attr('_src'))
    });

    function _imageLoaded()
    {
        alert('img loaded');
    }
<img scr='someUrl' id="testImage" />

jQuery('#testImage').bind('load',function(){
         alert ('iamge loaded');
});

to avoid race condition do as below

<img _src="http://www.caregiving.org/intcaregiving/flags/UK.gif" />
// i have added an underscore character before src



jQuery('img').each(function(){
        var _elm=jQuery(this);
        _elm.bind('load',_imageLoaded).attr('src',_elm.attr('_src'))
    });

    function _imageLoaded()
    {
        alert('img loaded');
    }
肤浅与狂妄 2024-10-01 19:39:56

不幸的是,我无法接受@TJ Crowder 和@Praveen 的出色答案,尽管两者都执行了所需的图像替换。 @Praveen 的答案需要更改 HTML(在这种情况下,我应该挂钩 标记自己的 error="" 事件属性。并通过以下判断网络活动,看起来如果您尝试使用在同一页面中刚刚进行 404 处理的图像的 url 创建新图像,该请求实际上会再次发送,图像服务器失败的部分原因是。至少部分是我们的流量;所以我真的必须尽我所能来减少请求,否则问题只会变得更糟。

@danp 对我的问题的评论中提到的 SO 问题实际上已经为我提供了答案,尽管它是我无法确认它是否适用于 IE 7 和 8、FF 和 webkit 浏览器,所以我有一个 try/catch; 在那里处理任何异常。最糟糕的情况是不会发生图像替换,这与现在不执行任何操作的情况没有什么不同,我正在使用的实现如下:

$(function() {
    $('img[src*=images.3rdparty.com]').each(
        function() {
            try {
                if (!this.complete || (!$.browser.msie && (typeof this.naturalWidth == "undefined" || this.naturalWidth == 0))) {
                    this.src = 'http://myserver.com/images/no_photo.gif';
                }
            } catch(e) {}
        }
    );
});

Unfortunately, I'm not able to accept either @TJ Crowder's nor @Praveen's excellent answers, though both do perform the desired image-replacement. @Praveen's answer would require a change to the HTML (in which case I should just hook into the <img> tag's own error="" event attribute. And judging by network activity, it look like if you try to create a new image using the url of an image that just 404ed in the same page, the request actually does get sent a second time. Part of the reason the image server is failing is, at least partly, our traffic; so I really have to do everything I can to keep requests down or the problem will only get worse..

The SO question referred to in @danp's comment to my question actually had the answer for me, though it was not the accepted answer there. I'm able to confirm that it works with IE 7 & 8, FF and webkit browsers. I'm doubtful it will work with older browsers, so I've got a try/catch in there to handle any exceptions. The worse case will be that no image-replacement happens, which is no different from what happens now without doing anything. The implementation I'm using is below:

$(function() {
    $('img[src*=images.3rdparty.com]').each(
        function() {
            try {
                if (!this.complete || (!$.browser.msie && (typeof this.naturalWidth == "undefined" || this.naturalWidth == 0))) {
                    this.src = 'http://myserver.com/images/no_photo.gif';
                }
            } catch(e) {}
        }
    );
});
一桥轻雨一伞开 2024-10-01 19:39:56

替代文本就足够了吗?如果是这样,您可以使用 img 标签的 alt 属性。

Would an alternate text be sufficient? If so you can use the alt attribute of the img tag.

因为看清所以看轻 2024-10-01 19:39:56

我想我已经明白了:当加载 DOM 时(或者甚至在 window.load 事件上)——毕竟,您希望在所有图像都完整时执行此操作获取),您可以通过创建一个新的 img 元素,挂钩其 loaderror 事件来追溯检查图像是否正常,然后循环抓取每个爆头的 src。类似于下面的代码(实时示例)。该代码只是匆忙完成的,它不是生产质量的 - 例如,如果您没有收到 loaderror,您可能需要一个超时,你假设错误。 (您可能必须替换检查器图像才能可靠地处理该问题。)

此技术假设重用 src 不会重新加载图像,我认为这是一个相当好的方法。可靠的假设(这当然是一个容易测试的假设),因为这种技术已永远用于预缓存图像。

我已经在 Linux 的 Chrome、Firefox 和 Opera 以及 Windows 的 IE6(是的,确实如此)和 IE8 上测试了以下内容。做了一份款待。

jQuery(function($) {
    var imgs, checker, index, start;

    // Obviously, adjust this selector to match just your headshots
    imgs = $('img');

    if (imgs.length > 0) {
        // Create the checker, hide it, and append it
        checker = $("<img>").hide().appendTo(document.body);

        // Hook it up
        checker.load(imageLoaded).error(imageFailed);

        // Start our loop
        index = 0;
        display("Verifying");
        start = now();
        verify();
    }

    function now() {
        return +new Date();
    }

    function verify() {
        if (!imgs || index >= imgs.length) {
            display("Done verifying, total time = " + (now() - start) + "ms");
            checker.remove();
            checker = undefined;
            return;
        }
        checker[0].src = imgs[index].src;
    }

    function imageLoaded() {
        display("Image " + index + " loaded successfully");
        ++index;
        verify();
    }

    function imageFailed() {
        display("Image " + index + " failed");
        ++index;
        verify();
    }

    function display(msg) {
        $("<p>" + now() + ": " + msg + "</p>").appendTo(document.body);
    }
});​

实例

I think I've got it: When the DOM is loaded (or even on the window.load event — after all, you want to do this when all images are as complete as they're going to get), you can retroactively check that the images are okay by creating one new img element, hooking its load and error events, and then cycling through grabbing the src from each of your headshots. Something like the code below (live example). That code was just dashed off, it's not production quality — for instance, you'll probably want a timeout after which if you haven't received either load or error, you assume error. (You'll probably have to replace your checker image to handle that reliably.)

This technique assumes that reusing a src does not reload the image, which I think is a fairly reliable assumption (it is certainly an easily testable one) because this technique has been used for precaching images forever.

I've tested the below on Chrome, Firefox, and Opera for Linux as well as IE6 (yes, really) and IE8 for Windows. Worked a treat.

jQuery(function($) {
    var imgs, checker, index, start;

    // Obviously, adjust this selector to match just your headshots
    imgs = $('img');

    if (imgs.length > 0) {
        // Create the checker, hide it, and append it
        checker = $("<img>").hide().appendTo(document.body);

        // Hook it up
        checker.load(imageLoaded).error(imageFailed);

        // Start our loop
        index = 0;
        display("Verifying");
        start = now();
        verify();
    }

    function now() {
        return +new Date();
    }

    function verify() {
        if (!imgs || index >= imgs.length) {
            display("Done verifying, total time = " + (now() - start) + "ms");
            checker.remove();
            checker = undefined;
            return;
        }
        checker[0].src = imgs[index].src;
    }

    function imageLoaded() {
        display("Image " + index + " loaded successfully");
        ++index;
        verify();
    }

    function imageFailed() {
        display("Image " + index + " failed");
        ++index;
        verify();
    }

    function display(msg) {
        $("<p>" + now() + ": " + msg + "</p>").appendTo(document.body);
    }
});​

Live example

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文