(function() {
var v8string = 'function%20javaEnabled%28%29%20%7B%20%5Bnative%20code%5D%20%7D';
var es6string = 'function%20javaEnabled%28%29%20%7B%0A%20%20%20%20%5Bnative%20code%5D%0A%7D';
if (window.devicePixelRatio) //If WebKit browser
{
var s = escape(navigator.javaEnabled.toString());
if (s === v8string) {
alert('V099787 detected');
} else if (s === es6string) {
alert('ES6 detected')
} else {
alert('JSC detected');
}
} else {
display("Not a WebKit browser");
}
function display(msg) {
var p = document.createElement('p');
p.innerHTML = msg;
document.body.appendChild(p);
}
})()
requestAnimationFrame =
window.requestAnimationFrame // Standard name
|| window.webkitRequestAnimationFrame // Fallback to webkit- (old versions of Chrome or Safari)
|| window.mozRequestAnimationFrame // Fallback to moz- (Mozilla Firefox)
|| false; // Feature not supported :(
// Same goes for cancelAnimationFrame
cancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || false;
if (!requestAnimationFrame) {
// Not supported? Build it by yourself!
requestAnimationFrame = function(callback) {
return setTimeout(callback, 0);
}
// No requestAnim. means no cancelAnim. Built that too.
cancelAnimationFrame = function(id) {
clearTimeout(id);
}
}
// Now you can use requestAnimationFrame
// No matter which browser you're running
var animationID = requestAnimationFrame(myBeautifulFunction);
function check() {
"use strict";
try { eval("var foo = (x)=>x+1"); }
catch (e) { return false; }
return true;
}
if (check()) {
var bar = (arg) => { return arg; }
// THIS LINE will always throw a SyntaxError in ES5
// even before checking for ES6
// because it contains illegal syntax.
} else {
var bar = function(arg) { return arg; }
}
function check() {
"use strict";
if (typeof Symbol == "undefined") return false;
try {
eval("class Foo {}");
eval("var bar = (x) => x+1");
} catch (e) { return false; }
return true;
}
if (check()) {
// The engine supports ES6 features you want to use
var s = document.createElement('script');
s.src = "es6script.js";
document.head.appendChild(s);
} else {
// The engine doesn't support those ES6 features
// Use the boring ES5 :(
}
Code in your es6script.js:
// Just for example...
"use strict";
class Car { // yay!
constructor(speed) {
this.speed = speed;
}
}
var foo = Symbol('foo'); // wohoo!
var bar = new Car(320); // blaze it!
var baz = (name) => { alert('Hello ' + name + '!'); }; // so cool!
Browser/engine detection
Like I said above, browser and engine detection are not the best practices when programming some JavaScript script. I'm gonna give you some background on this topic, just not to leave my words as a "random personal opinion".
When considering using the user agent string to detect which browser is being used, your first step is to try to avoid it if possible. Start by trying to identify why you want to do it.
[...] Are you trying to check for the existence of a specific feature?
Your site needs to use a specific Web feature that some browsers don't yet support, and you want to send those users to an older Web site with fewer features but that you know will work. This is the worst reason to use user agent detection, because odds are eventually all the other browsers will catch up. You should do your best to avoid using user agent sniffing in this scenario, and do feature detection instead.
Also, you're saying you use navigator.appVersion, but consider using another approach, because that one, together with many other navigator properties, is deprecated, and doesn't always behave like you think.
So, quoting from the MDN Documentation [link] again:
Deprecated: this feature has been removed from the Web standards. Though some browsers may still support it, it is in the process of being dropped. Do not use it in old or new projects. Pages or Web apps using it may break at any time.
Note: Do not rely on this property to return the correct browser version. In Gecko-based browsers (like Firefox) and WebKit-based browsers (like Chrome and Safari) the returned value starts with "5.0" followed by platform information. In Opera 10 and newer the returned version does not match the actual browser version, either.
<script>
// This script block should not compile on incompatible browsers,
// leaving the function name undefined.
// It can then be polyfilled with a function containing compatible syntax code.
function fame() {
/* incompatible syntax code such as arrow functions */
}
</script>
<script>
if (typeof fame !== "function") {
// alert("polyfill: fame");
function fame() {
/* compatible syntax code */
}
}
</script>
<script>
// main code
fame();
</script>
// If ES6 arrow functions are supported then the worker listener will receive true, otherwise it will receive an error message
(() => {
postMessage(true);
})();
Index.js
if (typeof (Worker) !== "undefined") {
var myWorker = new Worker('worker.js');
myWorker.onmessage = function (e) {
// arrow functions must be supported since we received message from the worker arrow function
}
myWorker.onerror = function (e) {
// the worker triggered an error so arrow function not supported (could explicitly check message for syntax error)
}
}