javascript - 使用setTimeout在浏览器中循环实现代笔效果

标签 javascript

我试图实现一个可以向用户“输入”消息的功能。像“T”-等待-“Th”-等待-“Tha”...我想出了这个函数,但它会等待,然后立即更新所有字母(而不是单独更新):

var tu = 'Thank you'
var timing = 1000
for (var i=0; i<=tu.length; i++) {
    setTimeout(function (){input.text(tu.slice(0, i))}, timing)
    timing = timing + 1000
}

但是当我这样做时(别笑),它起作用了..

setTimeout(function (){input.text('t')}, 400)
setTimeout(function (){input.text('th')}, 800)
setTimeout(function (){input.text('tha')}, 3000)
setTimeout(function (){input.text('than')}, 4000)
setTimeout(function (){input.text('thank')}, 5000)
setTimeout(function (){input.text('thank ')}, 6000)
setTimeout(function (){input.text('thank y')}, 7000)
setTimeout(function (){input.text('thank yo')}, 8000)
setTimeout(function (){input.text('thank you')}, 9000) 

任何人都可以解释为什么循环的行为与我的剪切粘贴工作不同吗?

最佳答案

这是 JavaScript 中奇怪的范围界定问题的示例。 setTimeout正在获取对 i 的引用,不是 i 的值for循环在任何 setTimeouts 之前完成执行,所以所有的setTimeout s 将为 i 使用相同的值,即tu.length .

您需要使用闭包来解决此问题:

var tu = 'Thank you'
var timing = 1000
for (var i = 1; i <= tu.length; i++) {
    (function (i) {
        setTimeout(function () {
            input.text(tu.slice(0, i))
        }, timing * i);
    })(i);
}

(另外,正如其他人指出的那样,您遇到了边界问题。我将 i < tu.length 更改为 i <= tu.length 。)

您可以see this in action on jsFiddle .

关于javascript - 使用setTimeout在浏览器中循环实现代笔效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15582593/

相关文章:

javascript - 使用anyOf查看对象名称?

javascript - 测试对象是否是 DOM 元素

javascript - AngularJS 中的工厂 "is not defined"

javascript - 从搜索 jquery 中删除区分大小写

javascript - 通过 charCodeAt 比较两个带有特殊字符的字符串

JavaScript ".call"不明白

javascript - Sammy.JS 在 app.run 上没有自动 runRoute?

javascript - 小计和总计自动计算

javascript - 完全检测另一个物体内部的物体

javascript - 有没有办法在调用对象的未定义函数时调用自定义函数?