The problem is here:
for (let i = 0; i < chars.length; i++) {
  // ...
  setTimeout(function() {
    chars[i].span.classList.add('high-light')
This is a bug in IE11. Variables declared with let syntax were officially introduced in ES2015, and IE11 was released in 2013 - although it does not throw a syntax error when encountering let, it does not conform to the specification. Specifically, variables declared with let in IE11 do not get block scoped - rather, they have function scope, just like var, so by the end of the loop, i is equal to chars.length, and chars[chars.length] is undefined, so trying to reference chars[i].span will throw an error.
I'd recommend avoiding for loops and using forEach instead, which will fix the problem and also let you avoid having to keep track of indicies:
chars.forEach(function(char) {
  // ...
  setTimeout(function() {
    char.span.classList.add('high-light')
    // ...
    // instead of referencing chars[i], reference char
You can also use the main closure inside loops example, though it's pretty ugly:
for (let i = 0; i < chars.length; i++) {
  (function(i) {
    // now, there will be a separate `i` argument for every iteration
    // ...
    setTimeout(function() {
      chars[i].span.classList.add('high-light')
      // ...
  })(i);
}
You can also consider automatically transpiling your code to be ES5 compatible with Babel.