Javascript 为什么我的计数器每次添加一个以上?
我正在使用jQuery创建一个测试,但不知道为什么在使用正确答案时,我的计数器变量“Javascript 为什么我的计数器每次添加一个以上?,javascript,jquery,Javascript,Jquery,我正在使用jQuery创建一个测试,但不知道为什么在使用正确答案时,我的计数器变量“count”似乎增加了不止一个 function nextQuestion(){ $('#submit').show(); $('#next').hide(); $('#result').text(''); $('#value').val(''); randomNumber = Math.floor((Math.random() * words.length));
count
”似乎增加了不止一个
function nextQuestion(){
$('#submit').show();
$('#next').hide();
$('#result').text('');
$('#value').val('');
randomNumber = Math.floor((Math.random() * words.length));
$('#englishWord').text(words[randomNumber][0]);
$('#submit').click(function(){
if ($('#value').val() == words[randomNumber][1])
{
$('#result').text("You are correct, well done");
$('#submit').hide();
$('#next').show();
$('#next').click(function(){
count = count + 1;
$('#score').text(count);
nextQuestion();
});
}
else
{
$('#result').text("That is incorrect, try again");
count = 0;
$('#score').text(count);
}
});
}
每次单击
#next
时,计数将增加一个以上,因为您正在向#next
元素的单击事件添加多个匿名侦听器。每个函数都独立地将1
添加到count
。因此,当单击#next
时,对于添加到#next
元素上的click
事件中的每个匿名侦听器,计数将增加1
每次点击#submit
和$(“#value”).val()==words[randomNumber][1]
时,您执行:
$('#next').click(function(){
count = count + 1;
$('#score').text(count);
nextQuestion();
});
这将导致一个新的匿名函数作为侦听器添加到#next
元素的click
事件中,以及任何已经侦听该事件的函数。因此,每次在#next
上出现单击事件时,都会调用多个函数,每个函数将计数增加1。每次点击#next
的总增加量取决于您收听该事件的功能数量
对于#submit
元素的单击事件,您也有同样的问题。这会通过向#next
元素的单击事件添加更多侦听器,导致计数进一步增加。第一次单击#submit
时,会添加一个侦听器。在第二个#submit
事件中,单击两个侦听器到#submit
单击
事件,每个侦听器向#下一个单击
事件添加另一个侦听器,使该事件总共有3个侦听器。因此,count
增加3。当您向每个事件添加越来越多的侦听器时,这将继续扩展
让代码只添加一次事件侦听器
解决方案是只分配这些单击事件一次:
$('#submit').click(function(){
if ($('#value').val() == words[randomNumber][1])
{
$('#result').text("You are correct, well done");
$('#submit').hide();
$('#next').show();
}
else
{
$('#result').text("That is incorrect, try again");
count = 0;
$('#score').text(count);
}
});
$('#next').click(function(){
count = count + 1;
$('#score').text(count);
nextQuestion();
});
function nextQuestion(){
$('#submit').show();
$('#next').hide();
$('#result').text('');
$('#value').val('');
randomNumber = Math.floor((Math.random() * words.length));
$('#englishWord').text(words[randomNumber][0]);
}
或者,使用命名函数并依赖以忽略添加相同侦听器的尝试。
另一种解决方案是使用单个命名函数,该函数在一个作用域中定义,这样就不会在每次调用添加它的代码时重新定义它。未使用添加的侦听器(例如,
)是使用添加的(jQuery在为添加事件侦听器提供的各种方法中使用此方法)。如果尝试将相同的函数添加到addEventListener()
,并对其他参数使用相同的值,则。这意味着,即使尝试使用相同的参数多次添加相同的函数,每个事件也只能调用一次。对于匿名函数,每次运行代码时都会单独定义该函数。因此,虽然代码是相同的,但所定义的函数与代码运行之前的任何时间都是分离的。因此,会添加多个副本
然而,仅仅因为函数有一个名称并不意味着它是在一个作用域中定义的,这将导致每次添加它时不会重新定义它。例如,在上面的代码中,如果#next
侦听器的函数是在#submit
侦听器中定义的,并且即使它有一个名称,每次运行#submit
侦听器时都会重新定义它。为了防止函数被重新定义,关键是如何以及在何处定义函数,而不仅仅是它是一个命名函数。但是,为了引用该函数,它必须有一个名称,或者与一个变量相关联。因此,您通常会发现,当有人说“命名函数”时,有一种假设,即它的定义方式通常不会重新定义。计数器是多少,count?tha Math.random()生成介于0和1之间的数字,我不明白你是怎么用它作为随机数的。如果计数器变量是count,你应该给出你问题的一个工作示例……这只是代码的一部分,随机生成器会生成一个介于1和“单词”数组长度之间的数字。错误提示:下次遇到这种情况时,在似乎无法正常工作的行前面放置一个警报`count=count+1;`,在这种情况下,您会看到它在第一次单击时执行一次,在第二次单击时执行两次,甚至更多。这可能足以让你自己找到答案。这基本上是正确的。但是命名函数不会有帮助——至少,如果函数是在“#submit”处理程序中定义的,那么命名函数不会有帮助。你也会遇到同样的问题。如果使用在外部作用域中定义的命名函数,则两个$('#next')。单击调用将使用相同的处理程序,而不是碰巧执行相同操作的不同处理程序。但我怀疑这会有帮助——我不相信它会检查函数的相等性。如果它确实起作用,那么重要的一点不是函数是否命名,而是在何处声明。在js中,函数是否命名并不重要。@DavidKnipe,您是正确的。我在写这篇文章时,假设命名函数的定义方式和范围都不明确,因此每次调用任何一个事件处理程序时都不会重新定义它。我已经重写了。但是,确实如此。