为什么我的计数器每次增加多个?

时间:2016-08-06 20:04:32

标签: javascript jquery

我正在使用jQuery创建一个测试,但无法解决为什么当使用正确的答案时,我的计数器变量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);
        }
    });
}

1 个答案:

答案 0 :(得分:3)

每次点击count时,

#next会增加多个,因为您要向click元素的#next事件添加多个匿名侦听器。这些功能中的每一项都独立地将1添加到count。因此,当点击#next时,count会为您添加到click元素上的#next事件的每个匿名侦听器提升1。

每次点击#submit$('#value').val() == words[randomNumber][1]时,您都会执行:

$('#next').click(function(){
    count = count + 1;
    $('#score').text(count); 
    nextQuestion();              
});

这会导致新的匿名函数被添加为#next元素的click事件的侦听器,以及已经侦听该事件的任何事件。因此,每次在click tehre上发生#next事件时,会调用多个函数,每个函数将count增加1. {{1}上每次点击的总增加量取决于你听过那个事件的函数数量。

#next元素的click事件存在同样的问题。通过向#submit元素的count事件添加更多侦听器,这会使click进一步增加。第一次单击#next时,会添加一个侦听器。在第二个#submit点击两个#submit #submit事件的听众,每个人都为click #next事件添加另一个监听器,共有3个监听器事件。因此,click上升了3.随着为每个事件添加越来越多的侦听器,这种情况会继续扩展。

让您的代码只添加一次事件监听器

解决方法是只分配一次点击事件:

count

或者,使用命名函数并依赖addEventListener()忽略尝试添加相同的侦听器。

另一种解决方案是使用单个命名函数,该函数在范围内定义,以便每次调用添加代码时都不重新定义。使用event attributes添加未使用addEventListener()添加的监听器(例如$('#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在其为添加事件侦听器提供的各种方法中使用此方法)。如果您尝试添加相同的函数,使用<div onclick="doSomething();">的其他参数的相同值,则additional listeners are discarded。这意味着即使您尝试使用相同的参数添加相同的函数,也不止一次,每个事件只会调用一次。使用匿名函数,每次运行代码时都会单独定义该函数。因此,虽然代码是相同的,但是定义的函数与代码运行的任何先前时间是分开的。结果,添加了多个副本。

但是,仅仅因为函数具有名称并不意味着它在范围中定义,导致每次添加时都不会重新定义它。例如,在上面的代码中,如果addEventListener()侦听器的函数是在#next侦听器中定义的,即使它有名称,每次{{1}时仍会重新定义它} listener被运行了。为了防止重新定义函数,关键是函数的定义方式和位置,而不仅仅是它是一个命名函数。但是,为了引用该函数,它必须具有名称,或者与变量相关联。因此,您通常会发现,当某人说出一个“命名函数”时,就会产生一种假设,即它的定义方式通常不会被重新定义。