Let's break down what your code is doing:
// Setting the element's text to this string (at the beginning)
tl.set("#message", { text: "this works well" });
// Setting the element's text to a random value in the array (at the beginning)
tl.set("#message", { text: function() { return getRandomValueFromArray(messages); } });
// Animating the message's color to red
tl.to("#message", 1, { color: "red" });
GSAP assumes that only the animations should be repeated when the timeline is replayed, not the .set() calls and and animations.
In order to have it do both, you should put the set call inside of the onRepeat callback. You also need to set the position in the timeline of it to 0, but I'm not quite sure why you need to do that (maybe @GreenSock or another mod can help me out with understanding why). The code would then look like this:
var messages = ["1", "2", "3", "4", "5"];
var tl = new TimelineMax({
repeat: -1,
onRepeat: function() {
tl.set("#message", { text: function() { return getRandomValueFromArray(messages); } }, 0);
}
});
function getRandomValueFromArray(a) {
return a[Math.floor( Math.random() * a.length )];
}
tl.set("#message", { text: "this works well" });
tl.to("#message", 1, { color: "red" });
https://codepen.io/ZachSaucier/pen/NZyvLG?editors=0010