如何降低执行功能的速度?

时间:2016-10-22 21:31:36

标签: javascript

我知道我可以使用setTimeout()来做到这一点,但我的情况有点关键。 这是一个例子:

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"/>

我上面提供的代码将我的文本作为输入并在指定的延迟后打印出来,但只有在每个字母输入后等到那个时间后它才有效。

总之,我希望它的工作方式如下: “我可以在0.8秒内输入一个单词,但它会在每个字母延迟0.8秒后输入每个字母”

3 个答案:

答案 0 :(得分:3)

您需要捕获数组中的每个更改,请尝试以下操作:

&#13;
&#13;
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()

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

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);
&#13;
#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;
}
&#13;
<div id="name"></div>
<p>some text</p>
<input id="typename" type="text" />
&#13;
&#13;
&#13;

这只是一个测试,似乎有效,但可能在某处有一些缺陷。

答案 1 :(得分:1)

这是我对此的看法。如果当前输出不是输入值的子字符串,它将清除现有文本。

将所有内容包装在单个变量中,以避免与任何现有脚本发生名称冲突并添加一些控件,以便更容易实现。

&#13;
&#13;
var iO = {
    interval: 800,
    inputSelector: '#input',
    outputSelector: '#output',
    
    updating: false,
    start: function () {
        iO.updating ||
        (   iO.updating = setInterval(iO.update, iO.interval),
                iO.update()
        )
    },
    stop: function () {
        clearInterval(iO.updating);
        iO.updating = false
    },
    update: function () {
        var i = document.querySelector(iO.inputSelector),
            o = document.querySelector(iO.outputSelector),
            $in = i.value,
            $out = o.innerHTML;
        if ($out == $in) {
            // update finished. stop.
            iO.stop();
            return
        }
        if (!$in.length) {
            // no input. clear output. stop.
            o.innerHTML = '';
            iO.stop();
            return
        }
        if ($out.length > $in.length || $in.indexOf($out) == -1) {
            // output > input or output not found in input. clear output.
            o.innerHTML = '';
        }
        if (typeof $in[$out.length] !== "undefined") {
            // next letter is defined. add it to output.
            o.innerHTML += $in[$out.length];
        }
        if (o.innerHTML == $in) {
            // update finished. stop.
            iO.stop();
        }
    }
};

document.getElementById("input").addEventListener("keyup", iO.start);
&#13;
body {
  background-color: #f5f5f5;
  margin: 0;
  padding: 0;
}
#input, #output {
  font-size: 2.1rem;
  line-height: 2.1rem;
  min-height: 4rem;
  min-width: calc(100vw - 6rem);
  max-width: 80vw;
  margin: 2rem auto 1rem;
  display: block;
  line-height: 2rem;
  padding: .5rem 1rem;
  box-sizing: border-box;
}
#output {
  background-color: white;
  border-radius: 2px;
  box-shadow: 0 1px 5px 0 rgba(0,0,0,.1),0 2px 2px 0 rgba(0,0,0,.07),0 3px 1px -2px rgba(0,0,0,.06);
  min-height: 10rem;
  padding: 1rem;
}
&#13;
<input id="input" type="text" />
<div id="output"></div>
&#13;
&#13;
&#13;

答案 2 :(得分:-2)

您希望在用户输入时使用输入创建闭包:

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

这将存储一个闭包,用于在设置超时时输入。我认为这就是你的期望。