How to handle “image corrupt or truncated” in fire

2019-03-17 22:40发布

问题:

PLUGIN

I am using a jQuery plugi called lazyload.

What this does is lazy load images - meaning it does not render them in the browser until the image is within the scope of the viewport.

This is useful when you have a page that has many images, for example, and you don't want it to spend forever with the initial load.

FIREFOX

Ok, so I am also using Firefox version 23.0.1

PROBLEM

The plug in is great, however when scrolling down after some images I start getting errors where the image doesn't load (just has a generic place holder for a broken image link) and in the console it logs:

Image corrupt or truncated: [image url]

It is not that there is a problem with the image. They all render fine individually.

It is not on a SPECIFIC image as it is random. If I load the page again, the images that were corrupt may load now, with other images returning a broken link and logging corrupt in the console.

I searched around for this, and it seems that there is some problem with simultaneous fetches for an <img> src tag.

Possibly there should be a delay set on the fetch, however you cannot always tell how long the delay should be. And if one image is larger than another, it could still conflict (with a static delay time, as opposed to a complete callback).

Therefore, I would like to request:

a) If anybody knows of a solution to this (such as catching when the error occurs and re-triggering the load image function)
b) If anybody can propose an $.extend() to the library above (lazyload) that would create a callback function and wait until all active fetches are complete before loading the next one (IF this is the problem - I am not sure if it is) I am not a jQuery ninja so I am a little lost on the code. I could figure it out, but it would probably be dirty...
c) if this is NOT the problem, then some direction as to how I can solve this would be appreciated

回答1:

As suggested on this answer to a problem similar to yours:

It appears that when changing the src attribute of the img tag, Firefox fires a load event. This is contrary to the HTML5 specification, which says that if the src attribute is changed, then any other fetch already in progress should be ended (which Firefox does), and no events should be sent. The load event should be sent only if the fetch was completed successfully. So I'd say that the fact that you get a load event is a Firefox bug.

And then:

The best option may be to create a new element each time you wish to change the src attribute.

Which makes sense. Inside lazyload code, you'll find this one part, that seems to be when the image loads, responding to an scrolling event that triggers appear:

    /* When appear is triggered load original image. */
    $self.one("appear", function() {
        if (!this.loaded) {
            if (settings.appear) {
                var elements_left = elements.length;
                settings.appear.call(self, elements_left, settings);
            }
            $("<img />")
                .bind("load", function() {

                    var original = $self.attr("data-" + settings.data_attribute);
                    $self.hide();
                    if ($self.is("img")) {
                        $self.attr("src", original);
                    } else {
                        $self.css("background-image", "url('" + original + "')");
                    }
                    $self[settings.effect](settings.effect_speed);

                    self.loaded = true;

You can put an AND operator followed by some flag or fuction return that verifies if the last image is already fully loaded on that part:

if ($self.is("img") && lastImageIsLoadde() === true) { /*pseudocode here*/

thus preventing that img src gets replaced before its correct time (since settings.placeholder is the image the script takes stand in the place of the one about to be loaded when scrolling) and see if it works for you.



回答2:

I would check first if you have an updated version of the lazyload library. https://github.com/tuupola/jquery_lazyload/blob/master/jquery.lazyload.min.js

Currently v 1.9.7 is the latest. It could be a bug they already fixed. ( changelog: https://github.com/tuupola/jquery_lazyload/blob/master/CHANGELOG.textile )

Secondly, wich jQuery version are you using? Maybe a very old jQuery with an old lazyload library causes this problem? (Or maybe the newest jQuery?)

If that's all fine, maybe you can look into how the lazyload is initiated? Do you have ajax-requests and re-initiate the lazyloading? (Should not cause problems, but you never know). Or try different doctype/html structure?

If nothing works, I would 'strip down' the html document to a really clean version where the lazyloading works (just localhost testing, or jsfiddle or something) and put back parts one by one. Eventually you should see where the functionality breaks.

With jQuery v1.9.1 and Lazyload v1.9.7 it should just work with this:

$('.lazy').lazyload();

Here is a jsfiddle for testing: http://jsfiddle.net/web_nfo/21qb88v1/

Or maybe Firefox is just the problem. Currently version 40 is the recent one. Maybe you also have a 'beta' version installed? Or safe-mode on?