首页 > 解决方案 > For 循环在 Firefox 上运行良好,但在 Chrome 上不行

问题描述

我试图理解为什么我的代码在 Firefox 而不是 Chrome 上运行良好。

基本上发生的情况是,在 Firefox 上,循环可以工作,它会在每次迭代和结束时在页面上打印输出。

在 Chrome 上,它只在循环结束时打印一些输出。

我读到这可能与我要求代码在页面上打印输出的方式有关,即 .textContent,但我也尝试使用 .innerHtml 并且问题仍然存在。

代码有点长,我确信有一种更简洁的编写方式,但这是我的第一个项目,这是我现阶段能做的最好的事情。谢谢您的帮助 :)

这是 html 的样子:

const forma = document.querySelector('form');
const out0 = document.getElementById('user-choice');
const out1 = document.getElementById('computer-choice');
const out2 = document.getElementById('game-result');
const out3 = document.getElementById('user-score');
const out4 = document.getElementById('computer-score');
const out5 = document.getElementById('final-result');


        // get a ramdom choice between Rock-paper-scissor from Computer

        let choices = ['rock', 'paper', 'scissors'];
        
        let randomValue  = function computerPlay() {

            let randomChoice = choices[Math.floor(Math.random() * choices.length)];
            
            out1.textContent = randomChoice;

            return randomChoice;

        };

       

    function game() {

        let userScore = 0;
        let computerScore = 0;

        // iterate the function playRound 5 times with a for loop
        for (let i = 0; i < 5; i++) {
        // prompt an initial message "Rock, paper, scissor" to ask the user to input one of the 3
        let sign = prompt("Rock, paper or scissors?");

        // use a function to compare the random choice from computer with what the user has input in the prompt and return a result
        function playRound(playerSelection, computerSelection) {
         
            
          if (playerSelection == "rock" && computerSelection == choices[0]) {
            i = i -1;    
            return "It's a tie! Play again!";
                

         } else if (playerSelection  == "rock" && computerSelection == choices[1]) {
                
                computerScore = computerScore + 1;
                out4.textContent = computerScore;
                // this is when the computer wins
                if(computerScore == 3) {
                    i = 5; // so that it practically breaks out of the loop
                    out5.textContent = "Unfortunately you lost the game :("   
                } else return "You lose this round! Paper beats rock.";

            } else if (playerSelection  == "rock" && computerSelection == choices[2]) {
                
                userScore = userScore + 1;
                out3.textContent = userScore;
                if(userScore == 3) {
                    i = 5;
                    out5.textContent = "Congratulations, you won the game!"
                } else return "You win this round! Rock beats scissors.";

            } else if (playerSelection  == "paper" && computerSelection == choices[0]) {
                
                userScore = userScore + 1;
                out3.textContent = userScore;
                if(userScore == 3) {
                    i = 5;
                    out5.textContent = "Congratulations, you won the game!"
                } else return "You win this round! Paper beats rock.";

            } else if (playerSelection  == "paper" && computerSelection == choices[1]) {
                i = i -1; 
                return "It's a tie! Play again!";

            } else if (playerSelection  == "paper" && computerSelection == choices[2]) {
                
                computerScore = computerScore + 1;
                out4.textContent = computerScore;
                if (computerScore == 3) {
                    i = 5;
                    out5.textContent = "Unfortunately you lost the game :("
                } else return "You lose this round! Scissors beat paper.";

            } else if (playerSelection  == "scissors" && computerSelection == choices[0]) {
                
                computerScore = computerScore + 1;
                out4.textContent = computerScore;
                if (computerScore == 3) {
                    i = 5;
                    out5.textContent = "Unfortunately you lost the game :("
                } else return "You lose this round! Rock beats scissors.";

            } else if (playerSelection  == "scissors" && computerSelection == choices[1]) {
                
                userScore = userScore + 1;
                out3.textContent = userScore;
                if(userScore == 3) {
                    i = 5;
                    out5.textContent = "Congratulations, you won the game!"
                } else return "You win this round! Scissors beat paper.";

            } else if (playerSelection  == "scissors" && computerSelection == choices[2]) {
                i = i -1; 
                return "It's a tie! Play again!";
            // this currently doesn't work as it tries to convert the playerSelection toLowerCase, as requested in the let playerSelection = sign.toLowerCase(), but it cannot because the sign is null and so it returns an error that sign is null
            } else if(playerSelection === '' || playerSelection === null) {
                i = 0;
                 
            } else {
                i = i -1; 
                return "I think you forgot how to play this game!"; 
            }    


            }
            // store the playerSelection argument value (equal to user input made lower case) in a variable
            let playerSelection = sign.toLowerCase();
            // store the computerSelection argument value (equal to radom choice determined by function randomValue) in a variable
            let computerSelection = randomValue();

            // print the user input made to lower case in the paragraph tag
            out0.textContent = sign;
            // print the return statement from the function in the out2 tag
            out2.textContent= playRound(playerSelection, computerSelection); 

        }


        }

   // run the function
   game();

这是我的 HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    <title>Document</title>
</head>
<body>
    
    
    <div>
        <form>
            <strong>Your choice:</strong>
            <output type="text" id="user-choice"></output>
        </form>
    </div>
    <div>  
        <form>
            <strong>Computer choice:</strong> 
            <output type="text" id="computer-choice"></output>
        </form>
    </div>

    <div>  
        <form>
           <strong>Result of this round:</strong> 
            <output type="text" id="game-result"></output>
        </form>
    </div>

    <div>  
        <form>
            <strong>User score:</strong> 
            <output type="number" id="user-score"></output>
        </form>
    </div>

    <div>  
        <form>
            <strong>Computer score:</strong>
            <output type="number" id="computer-score"></output>
        </form>
    </div>

    <div>  
        <form>
            <strong>Game result:</strong>
            <output type="text" id="final-result"></output>
        </form>
    </div>
    
    <script src="script.js"></script>

    
    
</body>
</html>

标签: javascript

解决方案


您可以使用window.requestAnimationFrame来强制浏览器呈现某些内容。但是,您需要对其进行承诺,因为 requestAnimationFrame 有一个回调,并且不直接返回承诺。

完成此操作后,您的代码应如下所示:

const forma = document.querySelector('form');
const out0 = document.getElementById('user-choice');
const out1 = document.getElementById('computer-choice');
const out2 = document.getElementById('game-result');
const out3 = document.getElementById('user-score');
const out4 = document.getElementById('computer-score');
const out5 = document.getElementById('final-result');


// get a ramdom choice between Rock-paper-scissor from Computer

let choices = ['rock', 'paper', 'scissors'];
let userScore = 0;
let computerScore = 0;

let randomValue = function computerPlay() {
    let randomChoice = choices[Math.floor(Math.random() * choices.length)];
    out1.textContent = randomChoice;
    return randomChoice;
};



async function game() {
    // iterate the function playRound 5 times with a for loop
    for (let i = 0; i < 5; i++) {
        // prompt an initial message "Rock, paper, scissor" to ask the user to input one of the 3
        let sign = prompt("Rock, paper or scissors?");

        // use a function to compare the random choice from computer with what the user has input in the prompt and return a result
        function playRound(playerSelection, computerSelection) {
            if (playerSelection == "rock" && computerSelection == choices[0]) {
                i = i - 1;
                return "It's a tie! Play again!";


            } else if (playerSelection == "rock" && computerSelection == choices[1]) {

                computerScore = computerScore + 1;
                out4.textContent = computerScore;
                // this is when the computer wins
                if (computerScore == 3) {
                    i = 5; // so that it practically breaks out of the loop
                    out5.textContent = "Unfortunately you lost the game :("
                } else return "You lose this round! Paper beats rock.";

            } else if (playerSelection == "rock" && computerSelection == choices[2]) {

                userScore = userScore + 1;
                out3.textContent = userScore;
                if (userScore == 3) {
                    i = 5;
                    out5.textContent = "Congratulations, you won the game!"
                } else return "You win this round! Rock beats scissors.";

            } else if (playerSelection == "paper" && computerSelection == choices[0]) {

                userScore = userScore + 1;
                out3.textContent = userScore;
                if (userScore == 3) {
                    i = 5;
                    out5.textContent = "Congratulations, you won the game!"
                } else return "You win this round! Paper beats rock.";

            } else if (playerSelection == "paper" && computerSelection == choices[1]) {
                i = i - 1;
                return "It's a tie! Play again!";

            } else if (playerSelection == "paper" && computerSelection == choices[2]) {

                computerScore = computerScore + 1;
                out4.textContent = computerScore;
                if (computerScore == 3) {
                    i = 5;
                    out5.textContent = "Unfortunately you lost the game :("
                } else return "You lose this round! Scissors beat paper.";

            } else if (playerSelection == "scissors" && computerSelection == choices[0]) {

                computerScore = computerScore + 1;
                out4.textContent = computerScore;
                if (computerScore == 3) {
                    i = 5;
                    out5.textContent = "Unfortunately you lost the game :("
                } else return "You lose this round! Rock beats scissors.";

            } else if (playerSelection == "scissors" && computerSelection == choices[1]) {

                userScore = userScore + 1;
                out3.textContent = userScore;
                if (userScore == 3) {
                    i = 5;
                    out5.textContent = "Congratulations, you won the game!"
                } else return "You win this round! Scissors beat paper.";

            } else if (playerSelection == "scissors" && computerSelection == choices[2]) {
                i = i - 1;
                return "It's a tie! Play again!";
                // this currently doesn't work as it tries to convert the playerSelection toLowerCase, as requested in the let playerSelection = sign.toLowerCase(), but it cannot because the sign is null and so it returns an error that sign is null
            } else if (playerSelection === '' || playerSelection === null) {
                i = 0;

            } else {
                i = i - 1;
                return "I think you forgot how to play this game!";
            }
        }

        // store the playerSelection argument value (equal to user input made lower case) in a variable
        let playerSelection = sign.toLowerCase();
        // store the computerSelection argument value (equal to radom choice determined by function randomValue) in a variable
        let computerSelection = randomValue();

        // print the user input made to lower case in the paragraph tag
        out0.textContent = sign;
        // print the return statement from the function in the out2 tag
        out2.textContent = playRound(playerSelection, computerSelection);

        await promisifiedRequestAnimationFrame();
    }
}

function promisifiedRequestAnimationFrame() {
    return new Promise((resolve, reject) => {
        window.requestAnimationFrame(() => {resolve()});
    })
}

// run the function
game();

那么究竟发生了什么变化呢?

  • 我们添加了一个函数,该函数返回一个在 requestAnimationFrame 完成执行时解析的 Promise。
  • 我们使 game() 异步。这允许我们使用“等待”

但为什么它会起作用?

好吧,警报、提示和确认应该会暂停代码,直到用户执行某些操作。Firefox 不允许直接向它们发送垃圾邮件,因此您在 FF 上的提示之间的时间间隔很短,但 Chrome 并不真正关心这一点。你想要很多提示吗?美好的!通过window.requestAnimationFrame与 await 结合使用,我们将强制 chrome 等到帧绘制完成。


推荐阅读