72

CSS:

.posting-logo-div {
}
.posting-logo-img {
  height: 120px;
  width: 120px;
}
.posting-photo-div {
  height: 5px;
  width: 5px;
  position: relative;
  top: -140px;
  left: 648px;
}
.posting-photo-img {
  height: 240px;
  width: 240px;
}

HTML:

<div id="image" class="posting-logo-div">
  <img
    src="../images/some-logo1.jpg"
    onerror="this.src='../images/no-logo-120.jpg';"
    class="posting-logo-img"
  />
</div>
<div id="photo" class="posting-photo-div">
  <img
    src="../images/some-logo2.jpg"
    onerror="this.src='../images/no-logo-240.jpg';"
    class="posting-photo-img"
  />
</div>

This doesn't seem to work in Chrome or Mozilla but does work in IE.

Mario Petrovic
  • 7,500
  • 14
  • 42
  • 62
Shahrukh
  • 1,486
  • 5
  • 16
  • 20

5 Answers5

200

This works:

<img src="invalid_link"
     onerror="this.onerror=null;this.src='https://placeimg.com/200/300/animals';"
>

Live demo: http://jsfiddle.net/oLqfxjoz/

As Nikola pointed out in the comment below, in case the backup URL is invalid as well, some browsers will trigger the "error" event again which will result in an infinite loop. We can guard against this by simply nullifying the "error" handler via this.onerror=null;.

Gianfranco P.
  • 10,049
  • 6
  • 51
  • 68
Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
  • 11
    This can be really dangerous if 'http://placekitten.com/100/100' does not exist, as the browser will hammer the 'http://placekitten.com/100/100' url continuously. See http://stackoverflow.com/questions/92720/jquery-javascript-to-replace-broken-images for a solution – Relefant May 21 '13 at 23:40
  • @Neromancer I've tested in Chrome: http://jsfiddle.net/GvJh3/1/. No infinite loop occurs. – Šime Vidas May 22 '13 at 01:13
  • 10
    @ŠimeVidas: that's because Chrome evaluates onerror only once, while all other browsers do it continuously - to avoid the loop it should look like this: `onerror="this.onerror=null; this.src='http://placekitten.com/100/100';"` – Nikola Bogdanović Dec 31 '13 at 15:03
  • Is there a way to perform on error for lazy load? I have src as loader.gif. But my original image loads in data-original attribute which is not triggering the onerror function – harishannam Mar 25 '14 at 17:37
  • @harishannam I'm assuming your script for lazy load takes the URL from the data-original attribute and sets it as the src of the image, or? – Šime Vidas Mar 27 '14 at 02:46
  • @ŠimeVidas Yeah the Lazy Load script which I am using has src : loader.gif and data-original has the original image. So IMG onerror is tracking error of src attribute only, not tracking the error in data-orignal. So apparently, the loader.gif loads and no error is triggered, but the browser console detects 404 errors for the original images. – harishannam Mar 27 '14 at 04:20
  • 1
    @harishannam A data-original attribute won't trigger those URLs to laod. Are you using a library for that? If yes, that library should provide an error handler. – Šime Vidas Mar 27 '14 at 21:45
  • You should not assign the attribute inside onerror to a data-original one - the element will only go into error mode when the src attribute is set by the lazy loader. It is at that point that the onerror will recover to set the src attribute (not a data-original) to a fallback image format. – Nepaluz Jan 09 '20 at 15:11
  • When used with multiple images on the same page, this is one of those few instances where **the use of `this` is mandatory.** Refraining to do so, would result in fallback images replacing wrong images; i.e. those that loaded well. This is due to some racing conditions. – Serge Stroobandt Apr 14 '20 at 21:38
3

This is actually tricky, especially if you plan on returning an image url for use cases where you need to concatenate strings with the onerror condition image URL, e.g. you might want to programatically set the url parameter in CSS.

The trick is that image loading is asynchronous by nature so the onerror doesn't happen sunchronously, i.e. if you call returnPhotoURL it immediately returns undefined bcs the asynchronous method of loading/handling the image load just began.

So, you really need to wrap your script in a Promise then call it like below. NOTE: my sample script does some other things but shows the general concept:

returnPhotoURL().then(function(value){
    doc.getElementById("account-section-image").style.backgroundImage = "url('" + value + "')";
}); 


function returnPhotoURL(){
    return new Promise(function(resolve, reject){
        var img = new Image();
        //if the user does not have a photoURL let's try and get one from gravatar
        if (!firebase.auth().currentUser.photoURL) {
            //first we have to see if user han an email
            if(firebase.auth().currentUser.email){
                //set sign-in-button background image to gravatar url
                img.addEventListener('load', function() {
                    resolve (getGravatar(firebase.auth().currentUser.email, 48));
                }, false);
                img.addEventListener('error', function() {
                    resolve ('//rack.pub/media/fallbackImage.png');
                }, false);            
                img.src = getGravatar(firebase.auth().currentUser.email, 48);
            } else {
                resolve ('//rack.pub/media/fallbackImage.png');
            }
        } else {
            img.addEventListener('load', function() {
                resolve (firebase.auth().currentUser.photoURL);
            }, false);
            img.addEventListener('error', function() {
                resolve ('https://rack.pub/media/fallbackImage.png');
            }, false);      
            img.src = firebase.auth().currentUser.photoURL;
        }
    });
}
Ronnie Royston
  • 16,778
  • 6
  • 77
  • 91
2

very simple

  <img onload="loaded(this, 'success')" onerror="error(this, 
 'error')"  src="someurl"  alt="" />

 function loaded(_this, status){
   console.log(_this, status)
  // do your work in load
 }
 function error(_this, status){
  console.log(_this, status)
  // do your work in error
  }
Mustkeem K
  • 8,158
  • 2
  • 32
  • 43
1

replace product.invoice_url to your dynamic url

<img onerror="this.onerror=null;this.src='https://upload.wikimedia.org/wikipedia/commons/1/14/No_Image_Available.jpg';" [src]="product.invoice_url" class="img-thump" >

css

  .img-thump{
    height: 120px;
    width: 170px;
  }
Shashwat Gupta
  • 5,071
  • 41
  • 33
1

In ReactJS:

const Avatar = ({className, src, alt, ...props}) => {
const handleOnError = (e) => {
    e.target.src =
      "https://www.kindpng.com/picc/m/22-223863_no-avatar-png-circle-transparent-png.png";
}
return (
  <div>
    {src ? (
      <img
        {...props}
        className={`defaultClass ${className}`}
        src={src}
        alt={alt}
        onError={handleOnError}
      />
    ) : (
      <img
        {...props}
        className={`defaultClass ${className}`}
        src={
          "https://www.kindpng.com/picc/m/22-223863_no-avatar-png-circle-transparent-png.png"
        }
        alt={alt}
      />
    )}
  </div>
);}

In the above code, handleOnError function is triggered whenever it detects an invalid src link so we can assign the default link in this function.

If you want to see the implementation of the onError attribute in react you can check this video:

How to make a perfect Avatar Component

Ankur Kunal
  • 139
  • 1
  • 4