这是范围问题,对吗?
编辑:http://jsfiddle.net/RPwLK/7/
在以下函数的第38行,其中displayBossMessage()本身被调用,变量“boss”似乎超出了范围。它应该包含当前boss的名称(字符串),当调用该函数时,它应该将它放回“boss”参数中。
但老板似乎总是未定义。我已经尝试在创建jQuery监听器之前创建一个变量,看它是否在范围内,但看起来好像不是。
或许我只是在一个缓慢的一天。 ; P
function displayBossMessage(boss,message,options,timer){
boss = bosses[boss];
//clear any possible lingering text/buttons
$(boss.messagebox).text('');
$(boss.optionsbox).text('');
displayMessage_CurrentBoss = boss;
//if no options provided, set a default "continue" button
if(options == ''){
options = {
'default' : {
'text' : 'Continue',
'func' : function(){}
}
}
}
$('#container div').hide();
$(boss.div).fadeIn(1500);
writeMessage(message,$(boss.messagebox),0);
setTimeout(function(){
$(boss.optionsbox).fadeIn(1000);
},3000);
//"listen" for a choice
var i = 0;
for(option in options){
$(boss.optionsbox).html($(boss.optionsbox).html() + '<button name="'+ i +'">'+ options[option].text +'</button> ');
$(document).on('click', (boss.div)+' button[name="'+i+'"]', function(){
options[option].func();
//close message screen or show defined response
if(typeof options[option].response != 'undefined'){
displayBossMessage(boss,options[option].response,'',true);
}else{
$(boss.div).hide();
$('#container div').fadeIn(1500);
}
});
}
if(timer){
//if they are afk/don't click after a minute, do it for them
setTimeout(function(){
$(boss.div+' button[name="0"]').click();
},60000);
}
}
希望我没有完全忘记并且错过了这么简单的事情。
* 编辑:老板变量(全局)*
答案 0 :(得分:1)
(更新了包含两种解决方案的#11的jsfiddle修订链接)
看起来这可能是一个工作小提琴:http://jsfiddle.net/RPwLK/11/
一个小问题:第30行有一个额外的'
和(第二个)alert
调用 - 字符串文字未正确关闭(或者另一个正在打开)。之后,我能够调查并得出以下结论(2个问题)......
第一个问题是变量覆盖:
function displayBossMessage(boss,message,options,timer){
boss = bosses[boss]; // this line, boss was a string, now it will be an object
以后在同一个函数中的用法:
if(typeof options[option].response != 'undefined'){
displayBossMessage(boss,options[option].response,'',true); // first arg is now an object
解决方案是创建对原始boss
的引用,如果它是一个字符串:
function displayBossMessage(boss,message,options,timer){
var origBoss = boss; // let's remember what it was in its original string form
boss = bosses[boss];
并像这样使用它:
if(typeof options[option].response != 'undefined'){
displayBossMessage(origBoss,options[option].response,'',true); // now we're dealing with a string ref
第二个问题是option
循环中对for
的引用。它总是引用 last 值,因为$(document).on('click'...
总是被延迟(异步)。有很多方法可以解决这个问题。我选择使用bind
并传入一个参数,并为每个特定的迭代传递option
的值。
请注意,原始option
位于异步函数中,但不在闭包中(for
不是闭包):
for(option in options){
//...
$(document).on('click', (boss.div)+' button[name="'+i+'"]', function(){
options[option].func(); // here option is always the last item in options
因此,在单击处理程序的回调函数中引入一个方便地称为option
的参数:
$(document).on('click', (boss.div)+' button[name="'+i+'"]', function(option){ // here
options[option].func(); // and now option is whatever the argument value is
并且不要忘记通过bind:
在函数声明中传递它 $(document).on('click', (boss.div)+' button[name="'+i+'"]', function(option){
options[option].func();
// ...
}.bind(this,option)); // here we're passing whatever option is for the specific iteration as the first argument of the callback function
注意,this
只是范围,第一个后面的bind
(see MDN)的每个后续参数都对应于函数定义中的参数。