为什么在刷新页面时localStorage的条目会被重置?

7
我正在为我的班级制作一个猜谜游戏,我们需要实现一个本地存储的记分系统。我以为我理解了这个概念,但它并没有按照我预期的方式工作。当我玩游戏时,值被存储在localStorage中,但是当我刷新页面时,值重置了...有什么见解吗?以下是我的脚本开头,下面是我的HTML文件。
编辑:我将得分初始化为1,原因是每当用户猜对,就会加4分(得到+3),当用户猜错时,会扣掉1分(得到-2)。每次单击重新开始按钮时,用户会再失去1分。
编辑2:为了更清楚,请把我的剩余脚本粘贴在下面:P
编辑3:JSfiddle很棒!http://jsfiddle.net/2pdaoeu6/
'use strict';
//Define a container for the game, its variables and its methods.
var game = {
  answerPosition: 0,   // position of the current answer in the answersList - start at 0
  display: '',         // the current dash/guessed letters display - ex '-a-a--r--t'
  wrong: '',           // all the wrong letters guessed so far
  answer: '',          // the correct answer - one word from game.answersList
  wrongCount: 0,       // the number of wrong guesses so far
  over: false,         // is the game over?
  score: 1,            // 1 - 1 = 0
  answersList: [       // list of answers to cycle through
    'JavaScript',
    'document',
    'element',
    'ajax',
    'jQuery',
    'event',
    'json',
    'listener',
    'transition',
    'window'
  ]
};



game.restart = function () {

    localStorage.setItem('localScore', game.score - 1);
    var localScore =  Number(localStorage.getItem('localScore'));
    // var localScore = localStorage.localScore;

    // Initialize the game at the beginning or after restart
    // Initialize the game variables - the model
    game.answer = game.answersList[game.answerPosition].toLowerCase(); // get the word for this round
    // use the modulo operator to cycle through the answersList
    game.answerPosition = (game.answerPosition + 1) % game.answersList.length;
    game.display = game.dashes(game.answer.length);
    game.wrong = '';
    game.wrongCount = 0;
    game.over = false;
    game.score = localScore;

    // Initialize the web page (the view)
    $('progress').val('0');  // initialize the progress bar
    $('#display').text(game.display);
    $('#wrong').text('');
    $('#guessedletter').val('');
    $('#score').text(localScore); // initialize score


    // The focus method invoked on an input element allows the user to type in that input without having to click it.
    $('#guessedletter').focus();
};


game.play = function () {
    // Invoked when the user clicks on GUESS
    if (game.over) {// if the game is over
        $('#wrong').text('Press RESTART to play again.');  // user has to restart
    } else {
        //if the game is not over yet
        var guess = $('#guessedletter').val().toLowerCase();
        if (game.check(game.answer, guess)) {
            // if the guess is valid
            $('#display').text(game.display);
        } else if (guess) {
            // If it's a wrong non-empty guess 
            game.wrong = guess + ' ' + game.wrong;
            game.wrongCount++;
            $('#wrong') .text(game.wrong);
            $('progress').val(game.wrongCount);
        }
        // reinitialize the guess
        $('#guessedletter') .val('');
        $('#guessedletter').focus();
        // check for a win or loss
        game.outcome();
    }
};

game.dashes = function (number) {
    // this function takes a number as a parameter
    // and returns a string with that many dashes
    var result = '';
    for (var i = 1; i <= number; i++)  {
        result = result + '-';
    }
    return result;  
};

game.check = function (answer, letter) {
    // Checks all occurrences of the letter guessed against game.answer. 
    // Returns true if the guess is correct and false otherwise. 
    // Updates the game dash display variable game.display if applicable.
    var position;
    var result = false;
    if (letter) {   // check that guess is not the empty string
        // Find the first occurrence of guess in the answer
        position = game.answer.indexOf(letter);
        // if the guessed letter is found in the answer
        if (position > - 1) {
            result = true;
        }
        while (position >= 0) {
            // update the dash display and find all remaining occurrences
            game.display = game.display.substring(0, position) + letter + game.display.substring(position + 1);
            // get the next occurrence
            position = game.answer.indexOf(letter, position + 1);
        }
    }
    return result;
};

game.outcome = function () {
    // check if the game is won or lost
    if (game.answer === game.display) {
        $('#wrong') .text('Congratulations! You win! +3 points.');
        // game.score = (game.score + 4);
    game.score = Number(localStorage.getItem('localScore')) + 4;
        // localStorage['localScore'] = Number(localStorage.getItem('localScore')) + 4;
        game.over = true;  // game is over.  User has to restart to play again
        setTimeout(function(){game.restart()}, 3000);
    } else if (game.wrongCount >= 10) {
        $('#wrong') .text('No more guesses; the answer was: ' + game.answer
            + '! -2 points :(');
        // game.score = (game.score - 1);
        game.score = Number(localStorage.getItem('localScore')) - 1;
        // localStorage['localScore'] = Number(localStorage.getItem('localScore')) - 1;
        game.over = true;  // game is over.  User has to restart to play again
        setTimeout(function(){game.restart()}, 3000);
    }
};

// Main program starts here
$(document).ready(function () {
    game.restart();
    $('#guessbutton').click(game.play);
    $('#restart').click(game.restart);
});





<!DOCTYPE html>
<html>
    <head>
            <meta charset="utf-8">
            <title>Guessing Game</title>
        <link rel="stylesheet" type="text/css" href="guess.css" media="all">
    </head>
    <body>
        <h2>Guess a Letter</h2>    
        <p id="display" class="letters"></p>
        <input id="guessedletter" type="text" maxlength='1' class="letters" autofocus>
            <div>            
        <input id="guessbutton" type="button" value="GUESS">
        </div>
            <p>Wrong Letters</p>
        <p id="wrong" class="letters wrong"> </p>       
        <progress value="0" max="10"></progress>
            <div> 
        <input id="restart" type="button" value="RESTART">
            </div> 
         <p>Score: <span id="score"></span></p>
        <script defer src="../scripts/jquery-1.11.3.js"></script>
        <script defer src="../scripts/guess.js"></script>
    </body>
</html>

你可能应该添加一个 http://jsfiddle.net/。 - Martin Thoma
本地存储只能写入字符串。而您正在尝试使用数字。可能会导致错误。https://developer.mozilla.org/en-US/docs/Web/API/Storage/setItem - perseus
1个回答

6
据我所见,您在应用程序加载时调用了game.restart()。在您的restart()方法内部,您正在执行以下操作:
localStorage.setItem('localScore', game.score - 1);

当您的应用程序启动时,每次都会重置localStorage密钥localScore,导致上一次的得分丢失。尝试检查是否存在值,如果存在,则跳过setItem,像这样:

game.restart = function () {
    // if the localScore is not set, initialize it with your default value
    // otherwise don't set the localScore -> it would overwrite the saved values
    if(localStorage.getItem('localScore') === null) {
         localStorage.setItem('localScore', game.score - 1);
    }
    // .... rest of your function
}

跳过setItem是什么意思? - demboiz
我更新了我的回答,并添加了一个代码示例,尚未测试,但您应该能够理解。 - 23tux

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接