簡體   English   中英

為什么我的計數器每次加一以上?

[英]Why is my counter adding more than one each time?

我正在使用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);
        }
    });
}

每次單擊#next count就會增加一個#next因為您#next元素的click事件添加多個匿名偵聽器。 這些功能中的每一個都獨立地加1 count 因此,當單擊#next時,對於您添加到#next元素上的click事件的每個匿名偵聽器, count都將增加1。

每次單擊#submit$('#value').val() == words[randomNumber][1]都會執行:

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

這將導致一個新的匿名函數被添加為#next元素的click事件的偵聽器,而其他任何匿名函數#next在監聽該事件。 因此,每次在#next上有一個click事件時, #next調用多個函數,每個函數會將count增加1。 #next上的每次單擊所增加的#next取決於您偵聽該事件的功能。

#submit元素的click事件存在相同的問題。 通過將更多偵聽器添加到#next元素的click事件中,這將導致count進一步增加。 首次單擊#submit將添加一個偵聽器。 在第二個#submit單擊上,兩個偵聽器分別發送給#submit click事件,每個偵聽器將另一個偵聽器添加到#next click事件,從而使該事件總共有3個偵聽器。 因此, count增加了3。隨着向每個事件添加越來越多的偵聽器,此count將繼續擴展。

讓您的代碼僅添加一次事件監聽器

解決方案是僅將這些點擊事件分配一次:

$('#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]);
}

或者,使用命名函數並依賴addEventListener()來忽略添加相同偵聽器的嘗試。

另一種解決方案是使用單個命名函數,該函數在范圍內定義,這樣,每次調用添加該函數的代碼時就不會重新定義該函數。 未使用事件屬性 (例如<div onclick="doSomething();"> )添加的偵聽器使用addEventListener()添加(jQuery在其提供的用於添加事件偵聽器的各種方法中使用此方法)。 如果您嘗試添加相同的函數,並且對addEventListener()的其他參數使用相同的值,則其他監聽器將被丟棄 這意味着即使您試圖多次添加具有相同參數的相同函數,每個事件只會調用一次。 使用匿名函數,每次運行代碼時都會分別定義該函數。 因此,雖然代碼相同,但是定義的功能與代碼運行之前的任何時間是分開的。 結果,添加了多個副本。

但是,僅因為函數具有名稱並不意味着在某個作用域中對其進行了定義,否則將導致每次添加該函數時都不會對其進行重新定義。 例如,在上面的代碼,如果該功能#next監聽器的內定義#submit監聽器,即使它有一個名字,它仍然會在每次重新定義時間#submit監聽器運行。 為了防止函數被重新定義,關鍵在於函數的定義方式和位置,而不僅僅是其是命名函數。 但是,為了引用該函數,它必須具有名稱,否則必須與變量關聯。 因此,您通常會發現,當有人說“命名函數”時,通常以不重新定義的方式進行定義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM