2

I saw a Code to make A default image To be shown when there is a 404 error when loading a image.

Something Like this:

<img src="img/article_1744408190.jpg" onerror="this.src = 'ImgAlt.jpg'">

But It has to call onerror function from each each Image. But how can I implement A method to catch all the onerror triggers by Javascript(or JQuery) and individually set the image SRC to default.jpg.Posting A sample Code will be useful

  • 2
    Yeah! Posting a sample code will be useful for us too! How have you tried solving the problem other than adding the `onerror` property on all images manually? – Luca Kiebel May 20 '18 at 15:01
  • More on how the `alt` attribute is meant to be used: https://html.spec.whatwg.org/#alt – T.J. Crowder May 20 '18 at 15:19
  • The only way I know how to do this is with [Service Worker](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers)s and adding a `fetch` event listener. It is _much_ simpler to add `onerror` handlers in a build step then to actually do this. – Benjamin Gruenbaum May 20 '18 at 15:19

2 Answers2

2

You can set the error event listener on window (global error handling) and check if he target is an image, if so change its src:

window.addEventListener("error", function(e) {              // when an error happens
    if(e.target.tagName.toLowerCase() === "img") {          // if the target is an image
        e.target.src = "default.jpg";                       // then change its src to whatever you want
    }
}, true);

window.addEventListener("error", function(e) {
    if(e.target.tagName.toLowerCase() === "img") {
        e.target.src = "http://via.placeholder.com/200/ff0000/000000?text=404";
    }
}, true);
<img src="http://example.com/nonExistingImage.jpg">
<img src="http://via.placeholder.com/200/00ff00/000000?text=OK">
ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73
  • 1
    Does the global error handler actually fire for `img` tags? – Benjamin Gruenbaum May 20 '18 at 15:17
  • @BenjaminGruenbaum Yes – ibrahim mahrir May 20 '18 at 15:21
  • 1
    Then can you please explain what I missed in my fiddle? It looks like this solution does not work. – Benjamin Gruenbaum May 20 '18 at 15:21
  • @BenjaminGruenbaum I've added a working example to the answer. – ibrahim mahrir May 20 '18 at 15:25
  • @BenjaminGruenbaum - Looks like the `alert` was the problem: https://jsfiddle.net/mvxke2en/3/ – T.J. Crowder May 20 '18 at 15:26
  • 1
    @ibrahimmahrir - Is this specified and/or documented anywhere? Does it work in mobile browsers? (BTW, that via.placeholder.com thing is really cool!) – T.J. Crowder May 20 '18 at 15:28
  • @T.J.Crowder the _alert_ was the problem :O That sounds like a bug to me. Will ping about it in the #whatwg room to see what they have to say. – Benjamin Gruenbaum May 20 '18 at 15:29
  • @T.J.Crowder Not sure if MDN count as "documented anywhere", but the second bullet point [**here**](https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror) seems to say just that. – ibrahim mahrir May 20 '18 at 15:32
  • @T.J.Crowder it does - the `error` event [here](https://html.spec.whatwg.org/multipage/webappapis.html#onerroreventhandler) - I recall it specified in the media element loading page but I can't find it. – Benjamin Gruenbaum May 20 '18 at 15:34
  • 1
    @ibrahimmahrir - :-) A lot of people think MDN is "official documentation," but it isn't, you're right to couch things a bit because it isn't official (just community-edited and very good). It usually links to sources, but the link in this case doesn't seem to say that it works im the way above. Frustrating. :-) – T.J. Crowder May 20 '18 at 15:36
  • @BenjaminGruenbaum - I know about the global error handler, I just meant the aspects of it that the above relies on -- that it fires for broken images, will have a target that is the element that failed, etc. – T.J. Crowder May 20 '18 at 15:38
  • Thanks Guys. Work Like A charm :) – The Bang Bandit May 20 '18 at 16:02
0

To do this, you need to hook the error event, then go back and check the images to see if any of them have already errored (before you hooked the event) to handle them. Along these lines:

var defaultImage = "ImgAlt.jpg";
$("img").one("error", function() {
    this.src = defaultImage;
}).each(function() {
    if (this.complete && !this.naturalWidth) {
        this.src = defaultImage;
        $(this).off("error");
    }
});

complete will be true when the image is broken. naturalWidth will be the natural width of the image, and either 0 or undefined if it's broken. Sadly that latter check is just about the only way to know the image is broken, since they lack any (blindingly-obviously-needed) error indicator after the event. (naturalWidth is supported by all modern browsers and also IE9-IE11; it is not supported by the truly-obsolete IE8.)


Note the assumption that none of the images you want to load is actually zero-width. Seemed like a safe assumption. :-)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • You probably want to add a delegating handler instead to deal with images added dynamically - otherwise this is pretty simple and works. – Benjamin Gruenbaum May 20 '18 at 15:21
  • 1
    @BenjaminGruenbaum - `error` doesn't bubble, even though the specification says it's supposed to. :-) There's a warning about that in the jQuery docs. – T.J. Crowder May 20 '18 at 15:38
  • Note the assumption that none of the images you want to load is actually zero-width - this is not safe assumption as most pixel codes are using `img` tag to load pixel – Vivek Jun 02 '18 at 12:09
  • @Vivek - Those are 1 pixel wide, though, not 0, surely? Can you even create a 0-width image in any of the standard formats? – T.J. Crowder Jun 02 '18 at 12:15
  • @T.J.Crowder pixels are not actual images, they are just api calls (for ex ``, in this case if call fails then it will fire up `error` event and `defaultImage` will load up, please correct me if I'm wrong. – Vivek Jun 02 '18 at 12:30
  • @Vivek - And yet, the response must define an image, and again, can you even define a zero-width image in any of the standard formats? But this is all a pointless digression anyway; if the OP is doing what they're doing, obviously they're not using Facebook pixels. The entire concern here is completely irrelevant. – T.J. Crowder Jun 02 '18 at 12:33