The previous discussion was mainly between @PaulOB and @Paul_Wilkins I was mostly a spectator then, but things have changed now and JS started making sense. I am redoing what was done in that discussion in small bites.
This was the final version of the codepen by PaulOB →
keep in mind that the time parameter on setTimeout is in milliseconds. You are currently telling your script to type a letter every tenth of a second. Also, setTimeout needs to call a function. You’re not passing it a function.
Also, if we’re going to use a variable increment, you don’t want to forEach, you want to for.
Right, so lets do some debugging. The old school way. Get out a bit of paper and a pencil. Metaphorically, for the moment, but as you code, it can be helpful.
Let’s assume, for the moment, that typeText[counter] is “Abe L” (Yes, i’m shorthanding it.)
What does your code do?
Take “Abe L”, and split it into its individual characters. (Note: This step is technically unnecessary, but we’ll roll with it).
We write down “onePresidentSplit”, and its value: ["A","b","e"," ","L"] on our piece of paper.
Okay. Next line.
For each of the characters in our array:
We now have to include a couple of other definitions:
Otherwise this line doesnt work. So we write down myElement, and <Element with ID 'type'> on our piece of paper, and we write down pos, and 0, on our piece of paper. Now we can go back to the previous line.
we set the innerHTML of the myElement to the current contents of that innerHTML plus onePresidentSplit[pos], which we can identify from our piece of paper that is “A” (because the 0th element of the array is “A”).
Next line.
Again, we need the value of increment. In this case it’s 1. So we write down increment and 1, and we scratch out the 0 next to pos, and replace it with 1.
We’re ending the forEach. So now we repeat this for all elements of the array. At the end of this loop, “Abe L” will be on the end of the myElement innerHTML, pos will be 5.
There has been no delay inserted into this code, so all of this happened at near-instantaneous speed, and the loop really has had no purpose.
There are now two major concerns presenting themselves to me.
ForEach plus Increment.
The example above worked great when increment was 1.
What happens when it’s 2?
Again, lets assume our word is “Abe L”, that our innerHTML starts off empty, and review the code:
forEach starts. element is "A", pos is 0.
onePresidentSplit[pos] is "A", so it's added to the innerHTML. innerHTML is now "A".
we add 2 to pos. pos is now 2.
Loop ends. Back to the beginning.
forEach starts. element is "b", pos is 2.
onePresidentSplit[pos] is "e", so it's added to the innerHTML. innerHTML is now "Ae"
we add 2 to pos. pos is now 4.
Loop ends. Back to the beginning.
forEach starts. element is "e", pos is 4.
onePresidentSplit[pos] is "L", so it's added to the innerHTML. innerHTML is now "AeL"
we add 2 to pos. pos is now 6.
Loop ends. Back to the beginning.
forEach starts. element is " ", pos is 6.
onePresidentSplit[pos] is an invalid array index. the array only has 5 elements.
Woops.
No Delay
Because the function operates all at once, there’s no delay between letters being added, so from the viewer’s perspective, it instantly appears at full length. This is a problem with the structure’s flow.
You’ve got the inkling that you need to use setTimeout, which is a valid statement, but how?
Rather than looping through the entire array in one go, instead have your ‘code’ (or function, more properly) add exactly 1 character to the string. If there are more characters to be added, set a Timeout to call the function again. Otherwise, you’re done.
Hi there, thanks for helping me. Sir, this is not a finished product I was trying to come one by one. I could not understand few things in your detailed analysis, but for now if you can help me in that limitation, how can I successfully implement setTimeout so that viewer can see the characters as actually typing.
Write me a function, typeCharacter, that takes a single string parameter, input.
The function should take the first character from the string, and add it to the screen.
If the string still has characters left, set a timer that:
calls typeCharacter again
does so 500 milliseconds from now,
sends the string, minus its first character, as the argument to typeCharacter. (Hint: Look at the syntax you posted above.)
Actually, I was carrying this forward from a previous discussion that happened on this platform whose link I shared. I understand that, and I had so much clarity of this, but I was trying something else, in small bites. Later I would have integrated the whole code.
My bad they were already there I didn’t share that with you.
Start Function
Remove first character (or first [increment] characters) from string, add it to output.
If the string is not empty:
Wait X milliseconds
Call function again with new string
End Function
I realized the gap in my understanding, the loop was firing all function in a flash, and those functions were rendering the output in browser in the same instance of time.