The timeouts can be delayed when the tab is backgrounded, which is causing these to get executed out-of-order. A simple workaround is to always fire the next event from the previous one. That is, instead of:
for (var i = 0; i < tw.length; ++i) {
delayPrint(i);
}
... instead do:
delayPrint(tw, 0);
... with:
function delayPrint(arr, index) {
if (index >= arr.length) {
return;
}
setTimeout(function() {
printElement(arr[index]);
delayPrint(arr, index+1);
}, 75);
}
function printElement(str) {
$('.codeWords').append(str);
}
In both cases, you should be aware that the timing is not guaranteed to be even... if you want to make the animation look smooth, you should figure out how much time elapsed since the previous invocation, and use that to determine how many characters to print out on the current iteration.