We are in the process of upgrading our React v17 app to v18. Currently we use react-app-polyfill as well as bowser to check if users are using a supported browser, and show a simple alert if they aren't. The app doesn't work properly on IE11 but the alert at least appears.
Now that we don't have any specific requirements to support IE11 it would be nice to remove the polyfill dependency, but obviously nothing within the React app will render without it, alert included.
Aside from the hacky solution of hardcoding text into the index.html root div, does anyone have a simple way of notifying users of a) IE11 and / or b) any unsuitable browser that their browser is not supported?
You may use a <script> tag with nomodule attribute inside your index.html like this:
<script nomodule>
alert('Sorry, you need to upgrade your web browser :(');
// or
window.location.href = 'a static page where you explain what to do';
</script>
This script will only be executed on web browsers that do not support ES Modules, which are Chrome <61, Firefox <60, Safari <11, Edge <16 and all versions of Internet Explorer (to mention only the most common ones).
I'd lean toward Valentin's nomodule approach.
But if you have a reason for not requiring module support, then I'd lean toward:
Doing a feature-check on some JavaScript language feature that you know IE doesn't have but you know your target browsers will have (like class, which is supported by all modern or even semi-modern browsers and markedly predated module support in browsers; but the specific choice is up to you).
If the feature-check fails, add your alert using something other than React.
For example:
function isObsolete() {
try {
(0, eval)("class Example { }");
return false;
} catch (e) {
return true;
}
}
// ...
if (isObsolete()) {
// ...add/perform warning...
}
Please am having a little difficulty to understand exactly what is the meaning of this attachment in this statements
var x = document.getElementById('myBtn');
if (x.addEventListner) {
//for all major browsers except IE 8 and earlier
x.addEventlistener('click', myFunction);
} else if (x.attachEvent) {
//for IE 8 and earlier versions
x.attachEvent('onclick', myFunction);
}
Can anybody tell me what this attachment stuff is all about? I did know addEventListener, but not attachEvent.
EventTarget.attachEvent()
Non-standard - This feature is non-standard and is not on a standards
track. Do not use it on production sites facing the Web: it will not
work for every user. There may also be large incompatibilities between
implementations and the behavior may change in the future.
This is a proprietary Microsoft Internet Explorer alternative to the standard EventTarget.addEventListener() method.
Edit:
The addEventListener() method is not supported in Internet Explorer 8 and earlier versions, and Opera 6.0 and earlier versions.
This is what your if statement is validating, to be able to support the other browsers.
Edit: that was the answer to the original question. But this answer is obsolete since the question has been modified since
It is a typo. x.attachment() should be x.attachEvent(). As documented in the question's code comments, this code is targeted at old IE browsers. So the typo only affects those. They do not have the addEventListener() method but have the attachEvent() method instead. The code in the question has probably never worked as expected with IE8 or earlier.
Is there a way to check whether a browser supports U2F or not?
I know that right now, Chrome is the only browser that officially does U2F, but there are addons for Firefox and there may also be customized browsers which may have gotten U2F.
I don't want to ditch such browsers like Google does, because the addon users wouldn't be able to use it.
I saw that GitHub seems to have a way to see it (because it distinguished between Firefox with and without addon), but I have no idea how to do that.
Use library caniuse-support, which uses information from the service caniuse.com (https://caniuse.com/#feat=u2f) and uses library bowser (browser detector):
const {
getSupport,
currentBrowser,
} = CaniuseSupport;
const test1 = getSupport("u2f"); // current browser
console.log(
"Get feature support of U2F current browser (" +
currentBrowser.id +
" " +
currentBrowser.version +
"):",
test1.level
);
CodePen sandbox
It's 2019 now and there actually have been some interesting improvements to the entire U2F stuff.
The U2F browser API has essentially been replaced by WebAuthn, and while sure that is throwing out some older browsers, there isnt really any relevant older browser that actually supports the U2F API which is still in a lot of use as chrome auto-updates anyway and chromium and its forks are basically the only browsers that natively supported U2F out of the box.
and with the new webauthn, you have functions you can actually check for, based on what I library I use has in an example document:
if (!navigator.credentials || !navigator.credentials.create) {
//try navigator.credentials.get for login instead of create
//tell the user
}
I want to identify if the broswer is IE then goto if block, other browser to else block in Java script.
I have one code here,
var browserName=navigator.appName;
if(browserName == "Microsoft Internet Explorer"){
IE code
}
else{
Other code
}
but i want to know is there any other way of implementing it?
Rather than do browser sniffing, you should do feature detection. Later versions of IE may support standards compliant stuff that in older versions you needed to work around or use MS-specific stuff.
Microsoft themselves have written up about the best way to do this and provide examples of both bad code (via sniffing) and good code (via detection). Make sure you go down the "good code" route.
I just started using this script to identify browser, version, and OS:
http://www.quirksmode.org/js/detect.html
If you are needing to use different code based on browser support for certain objects or methods, it's usually better to use object or method detection instead of browser detection. I use the browser detection for collecting statistics on my users, not for enabling or disabling features.
Quirksmode has a short article about why you don't use browser detection this way: http://www.quirksmode.org/js/support.html It's also linked from the browser detection script.
I found that This task is quite difficult as browsers all have similar names and different userAgent strings, so this is my Conditional statement to identify browsers.
I used this to identify the browser for different style sheets.
function styc()
{
var str = navigator.userAgent;
var res = navigator.userAgent.match(/Trident/);
var res2 = navigator.userAgent.match(/Firefox/);
if(res=="Trident"||res2=="Firefox")
{
//alert(navigator.userAgent);//for testing
document.getElementById('IE_fix').setAttribute("href", "IE_fix.css");
}
else
{
//alert("no");//for testing
document.getElementById('IE_fix').setAttribute("href", "mt_default.css");
}
}
Find a unique word in the userAgent string match it and check if the condition is true or not true depending on what you are doing.
The unique word I found for IE is Trident, and also identifies IE versions according to MicroSoft(not positive on this).
As the title states, I'd be interested to find a safe feature-based (that is, without using navigator.appName or navigator.appVersion) way to detect Google Chrome.
By feature-based I mean, for example:
if(window.ActiveXObject) {
// internet explorer!
}
Edit: As it's been pointed out, the question doesn't make much sense (obviously if you want to implement a feature, you test for it, if you want to detect for a specific browser, you check the user agent), sorry, it's 5am ;) Let me me phrase it like this: Are there any javascript objects and/or features that are unique to Chrome...
isChrome = function() {
return Boolean(window.chrome);
}
This answer is very outdated, but it was very relevant back then in the stone age.
I think feature detect is more usefull than navigator.userAgent parsing, as I googled Opera ambiguosity here. Nobody can know if IE16 will parse the /MSIE 16.0;/ regexp - but we can be quite sure, there will be the document.all support. In real life, the features are usually synonyms for the browsers, like: "No XMLHttpRequest? It is the f....d IE6!"
No nonIE browser supports document.all, but some browsers like Maxthon can scramble the userAgent. (Of course script can define document.all in Firefox for some reason, but it is easilly controllable.) Therefore I suggest this solution.
Edit Here I found complete resources.
Edit 2 I have tested that document.all is also supported by Opera!
var is = {
ff: window.globalStorage,
ie: document.all && !window.opera,
ie6: !window.XMLHttpRequest,
ie7: document.all && window.XMLHttpRequest && !XDomainRequest && !window.opera,
ie8: document.documentMode==8,
opera: Boolean(window.opera),
chrome: Boolean(window.chrome),
safari: window.getComputedStyle && !window.globalStorage && !window.opera
}
Using is simple:
if(is.ie6) { ... }
Not exactly an answer to the question... but if you are trying to detect a specific browser brand, the point of feature-checking is kind of lost. I highly doubt any other browsers are using the Chrome userAgent string, so if your question is 'is this browser Chrome', you should just look at that. (By the way, window.ActiveXObject does not guarantee IE, there are plug-ins for other browsers that provide this object. Which kind of illustrates the point I was trying to make.)
For all the standards nazis... sometimes you might want to use bleeding "standard technologies" which aren't just yet standard but they will be... Such as css3 features.
Which is the reason why I found this page.
For some reason, Safari runs a combo of border-radius with box-shadow just fine, but chrome doesn't render the combination correctly. So it would be nice to find a way to detect chrome even though it is webkit to disable the combination.
I've ran into hundreds of reasons to detect a specific browser/version which usually ends up in scrapping an idea for a cool feature because what I want to do is not supported by the big evil...
But sometimes, some features are just too cool to not use them, even if they aren't standardized yet.
So, if you accept Marijn's point and are interested in testing the user agent string via javascript:
var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
(Credit to: http://davidwalsh.name/detecting-google-chrome-javascript )
Here's a really nice analysis/breakdown of the chromes user agent string: http://www.simonwhatley.co.uk/whats-in-google-chromes-user-agent-string
I often use behavior/capability detection. Directly check whether the browser supports functionality before working around it, instead of working around it based on what might be the browser's name (user-agent).
A problem with browser-specific workarounds, is you don't know if the bug has been fixed or if the feature is supported now. When you do capability detection, you know the browser does or doesn't support it directly, and you're not just being browser-ist.
http://diveintohtml5.ep.io/everything.html
You shouldn't be detecting Chrome specifically. If anything, you should be detecting WebKit, since as far as page rendering is concerned, Chrome should behave exactly like other WebKit browsers (Safari, Epiphany).
If you need not only to detect WebKit, but also find out exactly what version is being used, see this link: http://trac.webkit.org/wiki/DetectingWebKit
But again, as other people said above, you shouldn't detect browsers, you should detect features. See this ADC article for more on this: http://developer.apple.com/internet/webcontent/objectdetection.html
One reason you might need to know the browser is Chrome is because it 'is' so damn standards compliant. I have already run into problems with old JavaScript code which I thought was standards compliant (by FF or Opera standards - which are pretty good), but Chrome was even more picky. It forced me to rewriting some code, but at times it might be easier to use the if(isChrome) { blah...blah ) trick to get it running. Chrome seems to work very well (I'm for standard compliance), but sometimes you just need to know what the user is running in grave detail.
Also, Chrome is very fast. Problem is, some JavaScript code unintentionally depends on the slowness of other browsers to work properly, ie: page loading, iframe loading, placement of stylesheet links and javascript links in page head, etc. These can cause new problems with when functions are really available to interact with page elements. So for now, you really might need to know...
I use this code to make bookmarks for each browser (or display a message for webkit)
if (window.sidebar) {
// Mozilla Firefox Bookmark
window.sidebar.addPanel(title, url,"");
} else if( window.external ) { // IE Favorite
if(window.ActiveXObject) {
//ie
window.external.AddFavorite( url, title);
} else {
//chrome
alert('Press ctrl+D to bookmark (Command+D for macs) after you click Ok');
}
} else if(window.opera && window.print) {
// Opera
return true; }
else { //safri
alert('Press ctrl+D to bookmark (Command+D for macs) after you click Ok'); }
There might be false positives since opera also has window.chrome object. As a nice solution I use;
var isOpera = !!window.opera || !!window.opr;// Opera 8.0+
var isChrome = !!window.chrome && !isOpera;
This solution almost always works.
However one thing I discovered is that, isChrome returns false in iPad Chrome version 52.0 as window.chrome returns false.
isIE: !!(!window.addEventListener && window.ActiveXObject),
isIE6: typeof document.createElement('DIV').style.maxHeight == "undefined",
isIE7: !!(!window.addEventListener && window.XMLHttpRequest && !document.querySelectorAll),
isIE8: !!(!window.addEventListener && document.querySelectorAll && document.documentMode == 8),
isGecko: navigator.product == 'Gecko',
isOpera: !!window.opera,
isChrome: !!window.chrome,
isWebkit: !!(!window.opera && !navigator.taintEnable && document.evaluate && navigator.product != 'Gecko'),