How do I make a 'typewriter' effect in Javascript effectively?

Viewed 66

I'm trying my hand at web-dev for the first time, and trying to mimic a sort-of terminal, and so I've been trying to make a 'typing' effect.

The first way I tried was with a FOR loop and the await function, but for whatever reason, when I use that here and pass a string with things like < br > it just prints that too, so it won't work.

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function cmdWrite(message, div){
    command.disabled = true;
    for (let i = 0; i < message.length; i++){
        await sleep(50);
        div.innerHTML += message.charAt(i);
    }
    div.innerHTML += "<br>" + "</br>";
    command.disabled = false;
    command.focus();
}

Another method I found was using an IF statement and setTimeout, but for some reason, it only prints one letter each time I call the function. Thanks for any help! I'm still brand new to the language so any advice is appreciated.

function typeWriter(txt, div) {
    if (i <= txt.length) {
      div.innerHTML += txt.charAt(i);
      i++;
      setTimeout(typeWriter, 100);
    }
  }

And the whole file here:

var i = 0;
var speed = 50;
var message = "";

var container = document.getElementById("container"); 
var command = document.getElementById("command");
var output = document.getElementById("output");

//dont get cursor lost
command.focus()

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function cmdWrite(message, div){
    command.disabled = true;
    for (let i = 0; i < message.length; i++){
        await sleep(50);
        div.innerHTML += message.charAt(i);
    }
    div.innerHTML += "<br>" + "</br>";
    command.disabled = false;
    command.focus();
}

function typeWriter(txt, div) {
    if (i <= txt.length) {
      div.innerHTML += txt.charAt(i);
      i++;
      setTimeout(typeWriter, 100);
    }
  }
  
command.onkeydown = function(){
    if (event.key === "Enter"){

        //declare message
        switch(command.value.toLowerCase()){
            
            case "help":
                message = help;
                break;

            case "aboutme":
                message = "aboutme";
                break;
        }

        //create oldOutput and move cmdWrite method up
        var oldOutput = document.createElement("div");

        container.insertBefore(oldOutput, command);
        typeWriter(message, oldOutput);
        
        output.innerHTML = "";

        //create oldCommand and clear command
        var oldCommand = document.createElement("div"); 
        oldCommand.innerHTML = command.value;

        container.insertBefore(oldCommand, oldOutput);

        command.value = "";
    }
}



//old command
//old output

//command
//output
1 Answers

Another method I found was using an IF statement and setTimeout, but for some reason, it only prints one letter each time I call the function. Thanks for any help! I'm still brand new to the language so any advice is appreciated.

You have two problems there

  1. i is not initialised.
  2. when you send typewriter again it gets sent without a value.

try this function

function typeWriter(txt, div) {
    let i = 0;

    typeWriterHandler = () => {
        txt = txt.slice(1);
        typeWriter(txt, div)
    }
    if (i < txt.length) {
        div.innerHTML += txt.charAt(i)
        i++;
        setTimeout(typeWriterHandler, 100);
    }

  }

Related