9

I am trying to attach an event handler for the onerror event (404 error) to a <link> element.

I have something like this on my page:

<link rel="stylesheet" type="text/css" href="dead/link.css" onerror="handle404Error()" />

It works fine on Chrome and Opera but it should work on IE9+ too. I found this, but I can't find a solution myself.

Is there a way to do that without writing an extra method to load styles dynamically?

NOTE: I didn't tag this question with 'jquery', so please don't use it in your answers.

Jonny C
  • 1,943
  • 3
  • 20
  • 36
marcel
  • 2,967
  • 1
  • 16
  • 25
  • [According to this](https://pie.gd/test/script-link-events/) it's only supported in Chrome 19+, Firefox 9+, iOS 6.0.0, and Safari 6.0.1. – redbmk May 11 '15 at 22:30

3 Answers3

9

In IE, the onerror event does not fire on invalid link URLs, but the onload event does.

In Chrome, the opposite is true: The onload event does not fire on invalid link URLs, but the onerror event does.

So you'll need to use both events:

<link rel="stylesheet" type="text/css"
      href="dead/link.css" 
      onload="handle404Error(this)"
      onerror="handle404Error(this, true)"
/>

function handle404Error(el, failed) {
  if(failed || (el.sheet.cssRules && !el.sheet.cssRules.length)) {
    //Failed!
  }
  else {
    //Success!
  }
}


Example using invalid URL:

http://jsfiddle.net/et0g2xg6/


Example using valid URL:

http://jsfiddle.net/et0g2xg6/1

Update August 2017, thanks to @Alex:

onerror is fired by Chrome and Firefox.
onload is fired by Internet Explorer.
Edge fires neither onerror nor onload.

Rick Hitchcock
  • 35,202
  • 5
  • 48
  • 79
  • Thanks, I had recently uninstalled Firefox. Will reinstall and troubleshoot. – Rick Hitchcock May 11 '15 at 22:40
  • Thanks. It works fine for me but is there an other way than check the css rules? with this solution it will also call `handle404Error()` when the css file do not contain css definitions... – marcel May 12 '15 at 09:06
  • I came up with the cssRules solution through experimentation. I haven't found another property or method that works as well. Still working on a Firefox solution and will update my answer when finished. – Rick Hitchcock May 12 '15 at 13:06
  • Update August 2017: `onerror` is fired by Chrome and Firefox. `onload` is fired by Internet Explorer. Edge fires neither `onerror` nor `onload`. – Alex Aug 14 '17 at 11:18
  • Thanks, @Alex. Updated with your comment. – Rick Hitchcock Aug 14 '17 at 21:28
1

Following solution works in Firefox, you just need to arrange function definition and function calling:

function handle404Error(el, failed) {
    if(failed || (el.sheet.cssRules && !el.sheet.cssRules.length)) {
        //Failed!
    }
    else {
        //Success!
    }
 }

 <link rel="stylesheet" type="text/css"
       href="dead/link.css" 
       onload="handle404Error(this)"
       onerror="handle404Error(this, true)"
 />
Jyoti Dhiman
  • 540
  • 2
  • 6
  • 17
0

IE When the link href is for an invalid domain url, e.g. not a 404, then IE throws a Access is denied when trying to access the cssRules property.

function load (e) {
  var cssRules;
  try {
    cssRules = e.target.sheet && e.target.sheet.cssRules;
  } catch (e) {
    cssRules = { length: 0 };
  }

  if (cssRules.length) {
    console.log('load', e);    
  } else {
    console.error('load error', e);
  }
}`
Adam
  • 2,082
  • 2
  • 19
  • 17