最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Confirming ES5 support - Stack Overflow

programmeradmin5浏览0评论

What are the best and simplest ways, in a Javascript (CoffeeScript) front-end application, to notify a user their browser is not supported, rather than letting it fail over unsupported ES5 features when they are randomly hit by the user? Say, I am writing something for only modern browsers, and I'd like to avoid a myriad of failures that old browsers would bump into wherever my code uses ES5-introduced features... by blocking non-compliant ES5 browsers?

ES5 introduced some syntax features, some of which I believe CoffeeScript relies on, and I would like my code to somehow avoid executing to begin with, if the browser does not support ES5, rather than tweaking shims, using Modernizr, or checking each CoffeeScript syntax subset to figure how backwards is it supported. Just ES5 and a clean "we're sorry your browser is too old" page for the rest of the world.

I do not wish to write code that tests every ES5 feature, nor necessarily rely on compliance tables such as / for checking the browser type and version (although, I would resort to the later, if no nicer alternatives...).

What are the best and simplest ways, in a Javascript (CoffeeScript) front-end application, to notify a user their browser is not supported, rather than letting it fail over unsupported ES5 features when they are randomly hit by the user? Say, I am writing something for only modern browsers, and I'd like to avoid a myriad of failures that old browsers would bump into wherever my code uses ES5-introduced features... by blocking non-compliant ES5 browsers?

ES5 introduced some syntax features, some of which I believe CoffeeScript relies on, and I would like my code to somehow avoid executing to begin with, if the browser does not support ES5, rather than tweaking shims, using Modernizr, or checking each CoffeeScript syntax subset to figure how backwards is it supported. Just ES5 and a clean "we're sorry your browser is too old" page for the rest of the world.

I do not wish to write code that tests every ES5 feature, nor necessarily rely on compliance tables such as http://kangax.github.io/es5-compat-table/ for checking the browser type and version (although, I would resort to the later, if no nicer alternatives...).

Share Improve this question edited Dec 16, 2013 at 22:13 kangax 39.2k13 gold badges100 silver badges135 bronze badges asked Dec 12, 2013 at 14:01 matanoxmatanox 13.7k22 gold badges96 silver badges179 bronze badges 1
  • modernizr tells you what HTML, CSS and JavaScript features the user’s browser has to offer. – Ricardo Commented May 4, 2016 at 19:54
Add a comment  | 

3 Answers 3

Reset to default 18

There's no magic solution here.

For each ES5-only functionality (either it's Object.* methods or String.prototype.* methods or new syntax — getters, setters, etc.) you have 3 options:

  1. Shim it.
  2. Test if it's supported before executing it and bail out if it's not.
  3. Let it fail (possibly using a crude global try-catch block).

Why?

Because there's no such thing as "ES5" browser.

"ES5" is not a boolean value that could be evaluated. As you've seen from the compat. tables, ES5 is a pretty big set of features. And those features were implemented by different browsers/platforms in chunks, at various times, and with various compliance.

Of course you can always come up with some kind of clever inference test:

var isEngineES5Compliant = 'create' in Object && 
                           'isArray' in Array && 
                           'x'[0] === 'x';

But I'm sure you understand how brittle that is.

If a browser supports one method and you try to call another method — which might or might not be available — well, nothing good usually comes out of it. There will be false positives/negatives and there will be failures.

You say that you're writing only for modern browsers, but how exactly do you define a modern browser? Is it the one that supports ES5 fully? Or at least a subset of ES5 that your code is using? In that case you need to know exactly what subset that is.

Having said that, if we absolutely had to to come up with inference test to determine full ES5 compliance, I would go with:

(function () { 
  "use strict";
  return Function.prototype.bind && !this;
}());

This checks support for "strict mode" (actually only part of strict mode but it will likely suffice) and presence of Function.prototype.bind.

Both of these features were among the last to be implemented by browsers, so we're looking at IE10+, Firefox 4+, Safari 6+, Chrome 13+, and Opera 12+.

Note that even some of those browsers are not fully ES5-compliant (but that compliance is mostly about obscure-ish features).

Now, if you want truly modern browsers... how about testing for ES6 features? :)

I'm thinking about using the following try catch to test for some subset of es6.

In chrome right now this works:

try {
    eval(`
        'use strict';

        class hello {
            get hello() { return 123; }
        }
    `);
} catch(e) {
   console.log('es6 classes are disabled :(')
}

Translating this to es5 to test for getters could look like:

try {
    (function() {
        eval('var dfojdfoj12 = { get hello() { return 123; } }');
    })();
} catch(e) {
   console.log('es5 getters do not exist')
}

To fail "gracefully" (like showing a proper explanation rather than a white page or garbled mess), we chose to remove styles and content using the approach described in Dialog for Unsupported Browsers

Testing for CSS Animations support and Function.prototype.bind (prior to loading any scripts like es5-shim) worked fine. Note that you'll need to load that shim if you want to test your stuff in PhantomJS

发布评论

评论列表(0)

  1. 暂无评论