Home > Back-end >  delay between for loop iterations
delay between for loop iterations

Time:05-05

Issue

I have a function that takes a list of strings, loops over them and prints each one to a new line. I have added in some CSS animations that take a few seconds to have the string fully displayed.

The issue I am facing is that I can't figure out a way to wait for the previous string to be fully displayed before beginning the animation of the next string. I've added a snippet below - sorry if I'm not explaining it well.

Intended Outcome

For each string in the array that we pass into the newComputerMessage(messages) function, it should print a new line but only after the previous line has completely been displayed.

let userInputs = [];
const textBox = document.querySelector(".textBox");
const userInput = document.querySelector(".userInput");
const letters = /^[A-Za-z] $/;
let user = {
  name: "",
  timeInterval: -1,
  halt: false,
  quit: false
};

function captureUserInput() {
  let text = userInput.value;
  userInput.value = "";
  return text;
}

function nameEntered() {
  enteredName = captureUserInput();
  if (!enteredName.match(letters)) {
    newComputerMessage(">>Please only use Letters");
  } else {
    user.name = enteredName;
    newComputerMessage([">>Hello there "   user.name, ">>Second message"]);
  }
}

function newComputerMessage(messages) {
  for (let index = 0; index < messages.length; index  ) {
    const newPElement = document.createElement("p");
    newPElement.innerHTML = messages[index];
    newPElement.setAttribute("class", "computerText");
    textBox.appendChild(newPElement);
  }
}
.textBox {
  width: max-content;
}

.computerText {
  color: black;
  font-family: monospace;
  overflow: hidden;
  border-right: 0.15em solid orange;
  white-space: nowrap;
  margin: 0 auto 0 0;
  letter-spacing: 0.15em;
  animation: typing 3.5s steps(30, end), blink-caret 0.5s step-end infinite;
  width: max-content;
}

/* The typing effect */
@keyframes typing {
  from {
    width: 0;
  }
  to {
    width: 100%;
  }
}

/* The typewriter cursor effect */
@keyframes blink-caret {
  from,
  to {
    border-color: transparent;
  }
  50% {
    border-color: orange;
  }
}
<body>

  <div >
    <div >
      <p >>>Hello, please enter your name below</p>
    </div>

  </div>

  <div >
    <input class='userInput' type="text" name="fname"><br>
    <input onclick="nameEntered()"  type="submit" value="Submit">
  </div>
  </div>

</body>

CodePudding user response:

You can use setTimeout as shown below. First snippet is a working example. Second snippet is how it would look in your code:

I have taken 3500 miliseconds because I noticed 3.5s as the time for your animation in your CSS. You can vary that as per your needs.

function newComputerMessage() {
  for (let index = 0; index < 3; index  ) {
    setTimeout(() => console.log('appending element'), 3500 * index);
  }
}

newComputerMessage();

So in terms of your code it will be:

function newComputerMessage(messages) {
  for (let index = 0; index < messages.length; index  ) {
    const newPElement = document.createElement("p");
    newPElement.innerHTML = messages[index];
    newPElement.setAttribute("class", "computerText");
    setTimeout(() => textBox.appendChild(newPElement), 3500 * index);
  }
}

  • Related