0

I have some JS using ES6 template literals that I want to ensure has a fallback for older browsers.

Normally to detect a javascript feature I would do the standard if statement to see if that feature is detected in the window object:

if("JavascriptFeature" in window){
    // do something with the feature
}

How would I do this with template literals in the context below though?

I have the code below which is basically used to ensure that a 100vh property works as desired on mobile / iPad, and I want to wrap the JS into a conditional that only fires if the browser can use template literals:

JS

function resizeSection(){
    // First we get the viewport height and we multiple it by 1% to get a value for a vh unit

    var vh = window.innerHeight * 0.01;

    // Then we set the value in the --vh custom property to the root of the document

    document.documentElement.style.setProperty('--vh', `${vh}px`);
}

resizeSection();
addEventListener("resize", resizeSection, false)

CSS

.heading-section {
    /* Use vh as a fallback for browsers that do not support Custom Properties */
    height: calc(100vh); 

    /*MODERN BROWSERS*/
    height: calc(var(--vh, 1vh) * 100);
}

Please note: this is not a duplicate of Detecting template literals in javascript which is a similar sounding question in a very different context.

pjk_ok
  • 618
  • 7
  • 35
  • 90
  • If the browser JavaScript environment does not understand template literal syntax, your code won't get a chance to run at all as it will fail with syntax errors. – Pointy Apr 09 '19 at 00:44

2 Answers2

2

Checks for syntax features should be made in an eval statement.

For instance, checking for string literals would look like

function supportsLiterals() {
  try{ return eval("''===``") }
  catch(e){ return false; }
}

console.log(supportsLiterals());

Now, you have to understand that knowing this has little benefit for your code: You won't be able to have this syntax anywhere in the code unsupporting browser will execute (well there would be ways, but so bad you shouldn't even think about it.

So this would be beneficial only if you had two versions of the code and if you were able to load them dynamically.

Instead, it's probably better to write your code with the newest feature and then transpile your code so that everyone can use it.

For instance, using the online version of Babel your code would transpile to

function resizeSection() {
  // First we get the viewport height and we multiple it by 1% to get a value for a vh unit
  var vh = window.innerHeight * 0.01; // Then we set the value in the --vh custom property to the root of the document

  document.documentElement.style.setProperty('--vh', "".concat(vh, "px"));
}

resizeSection();
addEventListener("resize", resizeSection, false);
Kaiido
  • 123,334
  • 13
  • 219
  • 285
0

Syntax checks happen before any code is run. A runtime that doesn't support the new syntax will not run any of the script at all; you can't "protect" portions of the script after parse time because it's too late.

You could have a <script> tag with a simple template literal that initializes some global symbol, and then check in a separate <script> whether that global symbol is present.

If the first <script> has a syntax error (because the JavaScript runtime is old) then it won't run. The second <script> will then know that the template literals either do or don't work.

However — that doesn't really do you a huge amount of good, because if they don't work, then any further code you import with template literals will also fail. Probably the best you can do is conditionally import the good code or the workaround code based on the above test.

Pointy
  • 405,095
  • 59
  • 585
  • 614