2

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
spook
  • 31
  • 1

1 Answers1

0

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);
    }

  }

yehsuf
  • 84
  • 9
  • 1
    `typeWriterHandler = (div) => {` creates a global function attached to the window. Always use `const`. – ggorlen Jul 31 '22 at 16:41
  • Huh, I just tried this and its even weirder, it only prints the first letter, and everytime I hit enter, its just the first letter over and over again? – spook Aug 01 '22 at 14:45
  • I feel like the issue has to do with the onkeydown? – spook Aug 01 '22 at 16:21
  • the function is working when I run it directly on the full text I pass as a parmeter but in your function, you are manipulating too much with the innerHTML. you should pass the full text to the function. – yehsuf Aug 01 '22 at 22:06
  • Here's the JSFiddle I'm trying it on where it's giving the Uncaught TypeError - am I doing something wrong? https://jsfiddle.net/spookrequiem/h29wk5u4/2/ thanks so much! – spook Aug 04 '22 at 10:25
  • i had a mistake with a this inside i edited it to fix it [fiddle](https://jsfiddle.net/fv39tnb6/14/) (Before I made the tests with console.log and not with a div.) – yehsuf Aug 05 '22 at 13:48