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.