Last month a client reported an issue with their website, saying that the navigation isn’t working on his new iPhone 6s Plus. After getting all browser details, I started to reproduce the error, but neither on my iPad with an identical iOS and Safari version nor on any emulator on browserstack.com the error occurred. So, I arranged a meeting with the client and debugged directly on his smartphone. After some testing I noticed an JavaScript exception QUOTA_EXCEEDED_ERR:DOM Exception 22
. I checked the code and found the error was caused by using localStorage.setItem();
. While we checked if localStorage is available 'localStorage' in window
we didn’t check for setItem();
properly and therefore our complete JavaScript failed.
This made me rethink my strategy of hiding elements when JavaScript is available. Typically I change the className of <html>
from .no-js
to .js
in the <head>
with JavaScript to avoid the FOUC. The problem with this method is if an error occurs, like described before, this will fail and probalby make parts of the site unusable.
Example #
To demonstrate it here is an example of a responsive navigation.
Navigation on big screens
Navigation with JavaScript disabled/unusable
JavaScript usable and navigation closed
JavaScript usable and navigation open
If you view the demo on a small screen you can see that the navigation is hidden and the button to trigger the navigation is visible if JavaScript is usable. If JavaScript is disabled or unusable the navigation is hidden and the navigation is shown.
Here is the same demo with a JavaScript error added. As you can see in this case the navigation is displayed the same way it would be if JavaScript was disabled. So whatever error may stop your JavaScript from working the site will still be usable.
Conclusion #
To avoid cases where JavaScript is available, but not usable I will use the following code in the future.
document.documentElement.className = document.documentElement.className.replace(/\bno-js\b/,'js');
window.onerror = function () {
document.documentElement.className = document.documentElement.className.replace(/\bjs\b/,'no-js');
}
Additional I will use Cut the mustard to check for features.
if('querySelector' in document && 'addEventListener' in window) {
// code here
} else {
document.documentElement.className = document.documentElement.className.replace(/\bjs\b/,'no-js');
}
There are many ways where JavaScript is not available or executed in a browser and by using window.onerror
we can handle them and show the same layout/functionality which would be shown for users who disabled JavaScript.