Jack Cole
Jack Cole

Reputation: 1804

error(function) on img element causing infinite loop when the replacement image doesn't load

My script appends to a table some code to load images. However, it interprets the image link from the contents of the table. This sometimes causes it to load errornouse images. I created a placeholder image that loads if the first image fails, however if this placeholder fails to load, then the script goes into an infinite loop.

$(document).ready(function() {
    $('tr[id^="mini"]').each(function(index) {
        var s = $(this).find('td:first');
        var product = s.text().replace(/\s+/g, '');
        s.append('<br><a href="/-p/' + product + '.htm" target="_blank">View Live</a><br><a title="Click for bigger image" href="/PhotoDetails.asp?ShowDESC=Y\&amp;ProductCode=' + product + '" onclick="window.open(\'/PhotoDetails.asp?ShowDESC=Y\&amp;ProductCode=' + product + '\',\'Option\',\'scrollbars=yes,menubar=no,status=no,location=no,width=600,height=640\'); return false;" target="_blank"><img src="/v/vspfiles/photos/' + product + '-0.jpg" border="0" style="max-width:150px;max-height:150px" id="monkey-inserted-image" /></a>');
    });
    // This checks for images that do not load //
    $('img#monkey-inserted-image').error(function() {
        $(this).removeAttr("id").attr("src", "/tamper/noimage1.png");
        // If this image fails to load, an infinite loop is created //
    });
});

I tried using .removeAttr() hoping that this would stop the loop, but it does not.

Upvotes: 2

Views: 1961

Answers (4)

T.J. Crowder
T.J. Crowder

Reputation: 1074485

You need to unregister the error handler when setting your placeholder:

$('img#monkey-inserted-image').error(function() {
    $(this).unbind("error").attr("src", "/tamper/noimage1.png");
    // No more infinite loop :-)
});

Upvotes: 4

Magus
Magus

Reputation: 15104

The infinite loop is "normal". You are listening to the error event on your image, so if your default placeholder image trigger an error, your function is called and you try again to put that placeholder image so the error event is triggered and you try again to put the placeholder ... well, i think you get it.

You can check the src attribute of your image. And if you are already handling a placeholder image, just do nothing (or a fallback).

$('img#monkey-inserted-image').error(function() {
    if ($(this).attr('src') == '/tamper/noimage1.png')) {
        // Do your fallback here
        return;
    }

    $(this).removeAttr("id").attr("src", "/tamper/noimage1.png");
    // If this image fails to load, an infinite loop is created //
});

Upvotes: 0

Fisch
Fisch

Reputation: 3815

When handling the error, you should unbind that event so that it will not fire infinitely if the replacement image does not load

$('img#monkey-inserted-image').on('error', function() {
        $(this).off('error').attr("src", "/tamper/noimage1.png");
        // If this image fails to load, an infinite loop is created //
    });

Upvotes: 0

musefan
musefan

Reputation: 48415

Why wouldn't you expect this? You are basically telling it to try again each time it fails, so obviously if the src is bad then it will fail each time.

The removeAttr() will not do what you think it does. The error event is already registered, if you are trying to un-register it then you need to do it a different way.

Perhaps like so:

$(this).unbind('error');

Upvotes: 4

Related Questions