5

I'm adding images to an HTML5 canvas using Javascript:

img = new Image(); 
img.addEventListener('load', loadCallBack, false);
img.src = image_url;

And then loadCallBack draws the image.

The problem is that sometimes the image_url refers to a broken or nonexistent image. When this happens, I get a 404 error in the console and the image on the canvas stays white. Instead, I'd like to be able to replace the image's src attribute with another image_url.

I tried the following and it did not work:

img.addEventListener("error", function(){console.log("404");});

How can I detect the 404s of the images?

Note: I'm still looking for a solution, as neither of the two posted so far has worked.

LonelyWebCrawler
  • 2,866
  • 4
  • 37
  • 57
  • 1
    The `error` event seems to work (in Chrome, at least): http://jsfiddle.net/qgJRF/ – bfavaretto Sep 06 '12 at 20:05
  • I've edited the title; `Image()` javascript class existed well before HTML5 (clarification). Since you mentioned canvas, I've left the HTML5 tag with your question. – Christian Sep 06 '12 at 20:11
  • But then it sounds like this question: http://stackoverflow.com/questions/92720/jquery-javascript-to-replace-broken-images – LonelyWebCrawler Sep 06 '12 at 20:14

2 Answers2

16

The same code as the Kostia's answer: just to compare the ugliness of jQuery and the beauty of vanilla javascript:

function brokenImage() { ... }

img = new Image();
img.onerror = brokenImage;
img.src = "invalid_img_name.png";​
Jan Turoň
  • 31,451
  • 23
  • 125
  • 169
  • 8
    Just remember that assigning directly to the onerror handler will overwrite any other error event handlers that might be assigned. Probably not a problem for simple cases - but most of the time it's better to use img.addEventListener("error"... - though then you have to handle all the cross browser issues with addEventListener. – Mr Speaker Jun 16 '13 at 11:27
  • 1
    Since the comment of MrSpeaker receives so many upvotes, it is important to emphasize that it is wrong: the concern against onerror attribute makes sense in object we do not own (like HTMLElement on page that is shared among all its javascript code). Here we own `img` object, so we are free to do with it what the heck we want and it is OK. "Most of the time it is better..." - it is not an argument, just vague feeling. Actually the comment is a nice example of social bandwagon antipattern. – Jan Turoň Jun 04 '20 at 21:12
4

Works in jQuery for me... http://jsfiddle.net/5v2qG/

img = new Image(); 
$(img).bind('error', function () {
      alert('error called');                                                
});
img.src = "invalid_img_name.png";​
Kostia
  • 6,284
  • 1
  • 18
  • 15
  • I'm looking into getting either of your solutions working, thanks. – LonelyWebCrawler Sep 06 '12 at 20:14
  • @LonelyWebCrawler are you using jQuery? it should work as long as you attach the .bind() event handler BEFORE you try and load an image src. – Kostia Sep 06 '12 at 21:05
  • Ah, I had the order wrong. Strangely, the console still spits out 404 messages, but the error function gets called. Thanks! – LonelyWebCrawler Sep 06 '12 at 21:08
  • I'm sorry to remove your Accepted Answer, but this is not working as I expected. I'll look into it. – LonelyWebCrawler Sep 06 '12 at 21:17
  • http://jsfiddle.net/5v2qG/2/ Works for me. Alert doesn't pop up with a valid image url... – Kostia Sep 06 '12 at 21:21
  • @LonelyWebCrawler Btw, yes, the console will spit out a 404. It HAS to do that because thats what triggers the error event. So logic is: 404 -> error handler -> change src to fallback url -> loads image. – Kostia Sep 06 '12 at 21:23