An iFrame lets you embed a website inside of another HTML document. It’s often used to add online content to otherwise offline publications. When a viewer is offline, the iframe fails completely, and the author doesn’t have control of what is displayed.
So how do we go about fixing that?
The onerror Event
Adding an onerror attribute looked like a promising solution…at first…because I was only testing in Firefox.
I tested 2 techniques
- Setting the srcdoc attribute, which lets you apply HTML code as the iframe content.
- Using the jQuery replaceWith method to replace the iframe tag.
Both worked quite well…
…until I tested Chrome and Safari.
Depending on the URL I used, I either got a silent error with an empty iframe, or content generated by the browser.
Adding the navigator.onLine test
Newer browsers (including Chrome and Safari) support the navigator.onLine property. So I added the following onload attribute to the iframe tag.
onload="if(navigator.onLine===false) eval(this.getAttribute('onerror'));"
Since I’m lazy and I don’t like to re-write (and re-writing introduces opportunities for mistakes), if the browser is offline, this will execute the code that was already written for the onerror attribute.
I used the strict equivalence operater (===), as opposed to the equivalence operator (==), to ensure that this would not be triggered if navigator.onLine was undefined, which would be the case in an older browser.
Putting it all together
This jsfiddle has the source code for 4 different examples.
I purposely wrote the code so that everything could be included with the iframe itself, because many of our in5 customers are pasting the iframe embed code into their InDesign documents for digital publication.
Alternatively, you could write a block of code that handles an entire document full of iframes.
Handling all iframes with a single block of code
This could also be done with in5 content, by attaching the JavaScript as an external resource.
Here’s how you would do the same exactly thing, but with a single code block (i.e., not hand-altering every iframe in your document).
$(function(){
$('iframe').each(function(index,elem){
$(elem).attr('onerror',"'srcdoc','<p>You need to be online to view this content.</p>');").attr('onload', "if(navigator.onLine===false) eval(this.getAttribute('onerror'));"); }); });
Caution: Using this global technique, you may also want to check to make sure you’re only altering iframes where the src attribute is online content (e.g., contains ://).
This simple message is just a proof-of-concept. You could also design an image behind your iframe and hide the iframe when offline. In that case you could use $(this).hide() if jQuery is available or this.style.display=”hidden” with plain, vanilla JavaScript.
Hope that helps you to handle your offline content!
Get updates from Ajar Productions
Sign up today and get the InDesign Split Text premium extension for free!
your post addresses the iframe problem i am trying to solve EXACTLY!
unfortunately, your solution posted at https://jsfiddle.net/justinputney/jpaaytc4/2/ does not work in any browsers.
i see you posted this article back in 2016. is there a chance you could revisit it any post a working update?
thank you!
It looks like the onerror attribute no longer works with iframes, though it does work with img tags:
https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_ev_onerror
This solution is probably a better approach at this point:
https://stackoverflow.com/questions/9534001/want-to-call-a-function-if-iframe-doesnt-load-or-loads/9576180#9576180