我正在制作一个RPG,并希望对话框显示一个打字效果(在对话框中输入一个字母)。我在setTimeout()
遇到了一个递归问题,我在这里问:
How to ensure a recursive function isn't called again before it returns
SO用户推荐"避免在setTimeout中使用字符串......应该在数年和数年前停止教授;性能杀手,如果你在用户创建的字符串中进行混搭,就很容易造成非严格的eval-context错误。"
因此,如果我不应该使用setTimeout()
,那么我怎样才能为屏幕上键入的字符串的每个字符添加延迟?
我能想到的一种方法是将变量计数器设置为x,并递减它(让我们说,设置i = 1000
,然后循环直到i = 0,然后再次重复...直到字符串完全输入)但这会更快吗?它会解决问题吗?它也没有让我很好地了解减少需要多长时间。在setTimeout()
中,您可以指定毫秒。
到目前为止,这就是我设计typeEffect的方式(它输入正常,但我可以继续点击继续重新运行脚本的类型按钮)。
typeEffect : function (index) {
$("#responseButton").prop('disabled', true); //wait until typing is done before user can press again
game.data.enableCycle = false;
setTimeout(function () {
$("#npc_dialog").append(game.data.NPCdialog.charAt(index));
index++;
if (index < game.data.NPCdialog.length) {
Utilities.typeEffect(index);
}
else {
game.data.enableCycle = true;
Utilities.hoverText(); //after type effect, replace appended letters with full dialog, run hoverText to split it into spans (for hover text)
$("#responseButton").prop('disabled', false);
$('#npc_dialog').html(game.data.NPCdialog);
}
}, 50);
},
答案 0 :(得分:2)
你应使用setTimeout
。您不应该在setTimeout
中使用字符串。
为:
setTimeout('foo(32)', 1000);
好:
setTimeout(function() {
foo(32);
}, 1000);
我可以看到的问题是,每次按下按钮时都会启动一个新的并行setTimeout
循环,而不会取消之前的循环。这是常见的模式:
var fooTimer = 0;
$(element).click(function(evt) {
// clear the previous timer, if any
if (fooTimer) {
clearInterval(fooTimer);
}
// start a new timer
fooTimer = setInterval(function() {
foo(32);
}, 1000);
}
需要注意的另一点是:setInterval
/ setTimeout
是唯一可行的方法。你不能使用循环作为延迟,因为这样你的函数永远不会放弃线程。由于JavaScript是单线程的,并且与UI重绘共享一个线程,因此您的屏幕永远不会更新。你需要等待运行沙漏旋转所有字母的所有循环,并且几乎任何东西都阻止你的浏览器,然后你会看到一切都出现了。也就是说,除非浏览器认为您的代码没有出错并询问您是否要终止坏脚本。
答案 1 :(得分:0)
您可以使用setTimeout()或setInterval();做这样的事情会是首选的(唯一的?)方式。
我认为另一个SO用户指的是在字符串中设置回调代码而不是使用函数引用的做法,这已经有一段时间了。