Towkir Towkir - 1 month ago 6
Javascript Question

How do I decrease the speed of executing a function?

I know I can use

setTimeout()
to do that but my case is a little critical.
Here is an example:



var nameinput = document.getElementById("typename");
var printed = document.getElementById("name");

function demo(){
setTimeout(function(){printed.innerHTML = nameinput.value.toLowerCase()}, 800);
}

nameinput.addEventListener("input", demo);

#name {
height: 50px;
width: 400px;
margin: 20px auto;
border: 1px solid lightgreen;
border-radius: 4px;
font-family: monospace;
font-size: 200%;
font-weight: 100;
line-height: 50px;
}

#typename {
font-size: 150%;
line-height: 40px;
height: 40px;
width: 30%;
min-width: 350px;
border: 1px solid skyblue;
display: block;
margin: 20px auto;
padding: 5px;
border-radius: 4px;
}

<div id="name"></div>
<p>some text</p>
<input id="typename" type="text"/>





The code I provided above takes my text as an input and prints it after the specified delay, but it works only if I wait till that time after each letter input.

In a word, I want it to work like:
"I can type a word in 0.8 sec, but it will type each of the letters after 0.8 sec of delay per letter"

Answer

you need to capture each change in an array, try this:

var nameinput = document.getElementById("typename");
var printed = document.getElementById("name");

var actions = []

function demo() {
  var old = actions.length ?
      actions[actions.length - 1].old : printed.innerHTML
  var str = nameinput.value.toLowerCase()

  return (
    old.length < str.length ?
    actions.push({
       f: add.bind(null, str.slice(-1)),
       old: str
      }) :
    old.length > str.length ?
    actions.push({
       f: del,
       old: str
      }) : null
  )
}

function play() {
  if (!actions.length)
    return
    
 var a = actions.shift()
 a.f()
}

function add(s) {
  printed.innerHTML += s
}

function del() {
  printed.innerHTML = printed.innerHTML.slice(0, printed.innerHTML.length - 1)
}

setInterval(play, 800)
nameinput.addEventListener("input", demo);
#name {
  height: 50px;
  width: 400px;
  margin: 20px auto;
  border: 1px solid lightgreen;
  border-radius: 4px;
  font-family: monospace;
  font-size: 200%;
  font-weight: 100;
  line-height: 50px;
}
#typename {
  font-size: 150%;
  line-height: 40px;
  height: 40px;
  width: 30%;
  min-width: 350px;
  border: 1px solid skyblue;
  display: block;
  margin: 20px auto;
  padding: 5px;
  border-radius: 4px;
}
<div id="name"></div>
<p>some text</p>
<input id="typename" type="text" />

this is just a test, seems to work, but may have some flaws somewhere.

Comments