Typewriter typing effect with JavaScript

OpenJavaScript 0

Last updated: September 5, 2022.

Using the setInterval() method, you can make some text appear one letter at a time inside a HTML element.

The effect is to make the text appear as if it is being typed live.

First, we cover the relatively simple case of writing text inside an element without any formatting.

After that, we look at how to type text across multiple paragraph elements.

Table of contents

Simple typewriter: writing inside a single element

To write text into a single element, first create an element to write into in HTML markup:

<div id="typed-content"></div>

Next, select that element in JavaScript, write the text you want to see typed and create a function that you can program the typing inside when called:

const outputDiv = document.getElementById('typed-content');

const txt = `Watch me as I get typed out before your very eyes using JavaScript's setInterval() function.`;

function typeText() {
  // Typewriter effect programmed here
}

The basic idea behind the function is to call setInterval() every x milliseconds, which each time writes the current character in txt to the output element in the DOM. Then, it increases the value of i (tracking the current character) by 1:

function typeText() {

// Variable to keep track of current character being typed:
let i = 0; 

// Execute a function every 50 milliseconds using setInterval():
setInterval(() => {
  outputDiv.innerHTML += txt.charAt(i); // Write current character to output div
  i++; // Increase the value of i by 1
},50);
  
}

This code works but setInterval() will continue running until it is stopped.

It is good practice to run clearInterval() when the value of i is equal to the character length of txt so that it doesn’t continue indefinitely in the background:

const txt = `Watch me as I get typed out before your very eyes using JavaScript's setInterval() function.`;

const outputDiv = document.getElementById('typed-content');

function typeText() {

  let i = 0;
  const timerId = setInterval(() => {
    outputDiv.innerHTML += txt.charAt(i);
    i++;
    if (i === txt.length) {
        clearInterval(timerId);
      }
  },50);
  
}

This solution is sufficient if you want to write a long text node inside of an element in the DOM.

But what if you want to write text across multiple paragraph elements?

Try it with the function above and <p> will appear verbatim because only a single character at a time is being written and rendered in the DOM.

Typewriting effect with multiple paragraphs

Like before, start by creating an element in the DOM and selecting it in JavaScript.

This time, create a multiline template string and use a special element tag of your choice where you want a new paragraph to begin.

I'm using <np> below for 'new paragraph'. But you can use your own tag name here!

<div id="typed-content"></div>

<script>
const outputDiv = document.getElementById('typed-content');

const txt = `Watch me as I get typed out before your very eyes using JavaScript's setInterval() function.<np>
You can determine the speed that this text is typed by setting the time between intervals in the code.<np>
This effect is created without the need for any external library.<np>
#VanillaJS`;
</script>

Now you want to split txt into an array by the custom tag name you entered in the text.

Then, append as many paragraph element to the DOM as there are array items after splitting txt.

You then want to write each character in the first array item to the first <p> element in the DOM. When you reach the last character, the first character of the second array item to the second <p> element. And so on.

Finally, you should clear the interval to prevent it running forever in the background.

Here's this process in code:

function typeText() {
  // Split text by custom tag for new paragraph into array
  const splittedTxt = txt.split('');
  // Create an array of new 

element and append to output element let pElements = []; splittedTxt.forEach((item, index) => { const p = document.createElement('p'); outputDiv.appendChild(p); }); // Select all newly appended

elements const allParas = outputDiv.querySelectorAll('p'); let i = 0; // Current character let currentPara = 0; // Current paragraph const timerId = setInterval(() => { // Start writing in current paragraph in DOM text from corresponding splitted array item allParas[currentPara].innerHTML += splittedTxt[currentPara].charAt(i); i++; // When reach the end of current splitted text item if (i === splittedTxt[currentPara].length) { currentPara++; // Move to next paragraph i=0; // Reset i // If end of splitted array has been reached if (currentPara === splittedTxt.length) { clearInterval(timerId); // ...clear interval } } },50); }

Related links