正如已经提到的,在咬你的部分是事件的反应,异步以及可能不是你会如何以及何时期待踢递归函数的组合。它更进一步,但这足以说明出现问题的地方,而无需进入JS之间的元编程和浏览器引擎之间的元编程。
现在,其他答案已经告诉你为什么它不会按照你的想法工作,我建议问题的根源在于你试图管理应该发生一次的事情(切换按钮),可能会发生一百次,如果你写了更多的代码并将其翻过来,可视化起来会更容易。
或许重构,看起来有点像这样,可能会使事情变得更简单:
var button = {
el : $("#responseButton"), // cache your references
setDisabled : function (state) { button.el.prop("disabled", state); },
enable : function() { button.setDisabled(false); },
disable : function() { button.setDisabled(true); },
handleClick : function() {
button.disable();
Utilities.typeEffect(0, function() { button.enable(); });
}
},
dialogBox = {
// if you're going to call this 100x in a row, cache it
el : $("#npc_dialog"),
append : function (text) { dialogBox.el.append(text); }
},
sec = 1000,
textSpeed = {
fast : 1/25 * sec, // 25x /sec
medium : 1/10 * sec, // 10x /sec
slow : 1/ 5 * sec // 5x /sec
};
button.el.on("click", button.handleClick);
Utilities.typeEffect = function (index, done) {
if (index >= game.data.NPCdialog.length) {
game.data.enableCycle = true;
return done();
} else {
var character = game.data.NPCdialog[index];
dialogBox.append(character);
setTimeout(function() {
Utilities.typeEffect(index+1, done);
}, textSpeed.fast);
}
};
你应该注意到,我改变了实际.typeEffect
的非常非常小的内部。
我做了什么做的是快速构建一个快速的button
抽象,它包含对元素的缓存引用(不要让jQuery在页面上查找它,每秒25x),添加一些quick'n'dirty帮助方法......然后我给出了事件处理的按钮控件,包括知道如何清理的时间。
如果你会发现,我给.typeEffect
一个参数,done
,和我通过它的参数是由button
定义的函数,它知道如何清理自己,当一切都完了。该函数并没有更大,然而,我现在通过传递回调来执行输入阻塞/解除阻塞一次。
更好的是,我可以保证它在递归开始之前就被阻塞了,并且在最后一次递归发生之后它就被解除阻塞,没有任何不明确的状态阻碍。
我也缓存了对话框,重新加快了这个过程;
这些天,jQuery确实有奇迹,但这仍然应该被缓存。
如果我把它进一步,我可能会做typeEffect
一个对话框,书写组件插件,使几种不同类型的影响可能在被丢弃。
我可能也开始传递递归运行它所关心的其他参数(文本速度,参考对话框等),以便它们更易于交换,并且该函数变得更加可重用(并且更容易看到它的工作原理)。
请注意,这不是真的的答案。这是解决方案,它不仅解决问题,而且说明未来如何预防问题。
如果可行,请使用它,如果不行,请勿使用。
如果这个概念有效,但它不是你的风格,然后改变它(尽管如此,避免使用setTimeout
中的字符串......应该在几年前停止教学;如果你是性能杀手,安全危害在用户创建的字符串中混搭,容易造成非严格的eval-context错误......所有的好东西)。
当然你会看到setTimeout,那里。 – Norguard
...看起来像我选错了一周,放弃嗅探胶水。也就是说,我相信它会是'.charAt(index)',然后'process(index + 1)',因为解析后缀的时候。 '.charAt(++ index)'是'.charAt(index + 1)'。 – Norguard
@Norguard - 谢谢,修正。 – Malvolio