简体   繁体   中英

I made a rock paper scissors game with javascript and I'm having trouble with keeping score, I really lost

 function computerPlay() { let [min, max] = [1, 3] let randomNumber = Math.floor(Math.random() * (max - min + 1)) + min; if(randomNumber == 1) return 'ROCK' else if(randomNumber == 2) return 'PAPER' else return 'SCISSORS' } function play(playerSelection, computerSelection) { let move = playerSelection; let com = computerSelection; if(move == 'ROCK' && com == 'SCISSORS') return 'ROCK beats SCISSORS'; else if(move == 'ROCK' && com == 'PAPER') return 'PAPER beats ROCK' else if(move == 'SCISSORS' && com == 'ROCK') return 'ROCK beats SCISSORS' else if(move == 'SCISSORS' && com == 'PAPER') return 'SCISSORS beat PAPER' else if(move == 'PAPER' && com == 'SCISSORS') return 'SCISSORS beat PAPER' else if(move == 'PAPER' && com == 'ROCK') return 'PAPER beats ROCK' else if(move == com) return 'DRAW' } let playBtn = document.querySelector('.play-btn'); let container1 = document.querySelector('.container1'); playBtn.addEventListener('click', makeContainer); // This is the function that creates the page that needs the player's input(rock, paper or scissors) function makeContainer() { container1.remove(); let con = document.createElement('div'); con.classList.add('container'); let h1 = document.createElement('h1'); h1.classList.add('one'); h1.textContent = 'ROCK PAPER SCISSORS'; let h12 = document.createElement('h1'); h12.classList.add('two'); h12.textContent = 'ROUND 1'; let h13 = document.createElement('h1'); h13.classList.add('three'); h13.textContent = 'MAKE YOUR MOVE'; let buttons = document.createElement('div'); buttons.classList.add('buttons'); let btn1 = document.createElement('div'); btn1.classList.add('rock'); let span = document.createElement('span'); span.textContent = 'ROCK'; btn1.append(span); let btn2 = document.createElement('div'); btn2.classList.add('paper'); let span2 = document.createElement('span'); span2.textContent = 'PAPER'; btn2.append(span2); let btn3 = document.createElement('div'); btn3.classList.add('scissors'); let span3 = document.createElement('span'); span3.textContent = 'SCISSORS'; btn3.append(span3); buttons.append(btn1, btn2, btn3); con.append(h1, h12, h13, buttons); document.body.append(con); const container = document.querySelector('.container'); const rock = document.querySelector('.rock'); const paper = document.querySelector('.paper'); const scissors = document.querySelector('.scissors'); [rock, paper, scissors].forEach((c) => c.addEventListener('click', (e) => { // console.log(e.target); containerDisappear(container, c) })); } // This function removes the makeContainer page(the one that shows rock paper scissors) and adds a transition to it function containerDisappear(con, r) { let choi = r; con.style.transitionProperty = 'opacity'; con.style.transitionDuration = '1s'; con.style.opacity = '0'; setTimeout(() => con.remove('container'), 1000); animation(choi); } // This function displays the animation that pops up after the the makeContainer page has disappeared function animation(r) { let choic = r; const waitdiv = document.createElement('div'); waitdiv.classList.add('waitdiv'); const div1 = document.createElement('div'); const div2 = document.createElement('div'); const div3 = document.createElement('div'); div1.classList.add('div1'); div2.classList.add('div2'); div3.classList.add('div3'); div1.textContent = 'ROCK...'; div2.textContent = 'PAPER...'; div3.textContent = 'SCISSORS...'; waitdiv.append(div1, div2, div3); document.body.append(waitdiv); setTimeout(() => { div1.style.transitionProperty = 'opacity'; div1.style.transitionDuration = '.6s'; div1.style.opacity = '1'; }, 600); setTimeout(() => { div2.style.transitionProperty = 'opacity'; div2.style.transitionDuration = '.6s'; div2.style.opacity = '1'; }, 1200); setTimeout(() => { div3.style.transitionProperty = 'opacity'; div3.style.transitionDuration = '.6s'; div3.style.opacity = '1'; }, 1800); setTimeout(() => { waitdiv.style.transitionProperty = 'opacity'; waitdiv.style.transitionDuration = '.3s'; waitdiv.style.opacity = '0'; waitdiv.remove(); }, 2400); setTimeout(() => { results(choic) }, 2400); } // This function displays the player's move vs the computer's move and then displays information about who lost /* Theres a 0:1 right at the bottom of this page, it's static, it doesn't update after each move, it's actually one of the things I'm struggling with */ function results(c) { const cShoot = document.createElement('div'); cShoot.classList.add('container-shoot'); const shoot = document.createElement('h1'); shoot.classList.add('shoot'); const round = document.createElement('h1'); round.classList.add('round'); const versus = document.createElement('div'); versus.classList.add('versus'); const v = document.createElement('div'); v.classList.add('v'); const h6 = document.createElement('h6'); const choice = document.createElement('div'); choice.classList.add('choice'); const vs = document.createElement('div'); vs.classList.add('v'); const v2 = document.createElement('div'); v2.classList.add('v'); const choice2 = document.createElement('div'); choice2.classList.add('choice'); const h62 = document.createElement('h6'); // ----------------second part--------------------------------------- const info = document.createElement('div'); info.classList.add('info'); const h2 = document.createElement('h2'); const h3 = document.createElement('h3'); const span = document.createElement('span'); // ---------------------third part------------------------------------ const score = document.createElement('div'); score.classList.add('score'); const span2 = document.createElement('span'); span2.classList.add('player'); const span3 = document.createElement('span'); span3.classList.add('colon'); const span4 = document.createElement('span'); span4.classList.add('com'); // ---------------------time to append stuff-------------------------------------------- cShoot.append(shoot, round, versus, info, score); versus.append(v, vs, v2); v.append(h6, choice); vs.textContent = 'VS'; v2.append(choice2, h62); info.append(h2, h3); h3.append(span); span2.textContent = '0'; span3.textContent = ':'; span4.textContent = '1'; score.append(span2, span3, span4); // ----------------adding text-------------------------------------------- shoot.textContent = 'SHOOT!!!'; round.textContent = 'ROUND 1'; h6.textContent = 'YOU'; choice.textContent = (c.classList.value == 'rock') ? 'ROCK' : c.classList.value == 'paper' ? 'PAPER' : c.classList.value == 'scissors' ? 'SCISSORS' : null; vs.textContent = 'VS'; choice2.textContent = computerPlay(); h62.textContent = 'COM'; h2.textContent = play(choice.textContent, choice2.textContent); span.textContent = s(); if(span.textContent == 'YOU WIN THIS ROUND') span.style.color = 'green'; else span.style.color = 'red' // -------------------------function------------------------------------------------- function s() { if(choice.textContent == 'ROCK' && choice2.textContent == 'SCISSORS') { return 'YOU WIN THIS ROUND' } else if(choice.textContent == 'ROCK' && choice2.textContent == 'PAPER') { return 'YOU LOSE THIS ROUND' } else if(choice.textContent == 'SCISSORS' && choice2.textContent == 'ROCK') { return 'YOU LOSE THIS ROUND' } else if(choice.textContent == 'SCISSORS' && choice2.textContent == 'PAPER') { return 'YOU WIN THIS ROUND' } else if(choice.textContent == 'PAPER' && choice2.textContent == 'SCISSORS') { return 'YOU LOSE THIS ROUND' } else if(choice.textContent == 'PAPER' && choice2.textContent == 'ROCK') { return 'YOU WIN THIS ROUND' } } // -------------------------------------------------------------------------- document.body.append(cShoot); // cShoot is the first variable that was created inside this function, it's the div tha holds everything on this page }
 * { margin: 0; padding: 0; box-sizing: border-box; color: white; } body { background-color: #333; } .container { height: 100vh; text-align: center; position: relative; opacity: 1; } .buttons { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); display: flex; column-gap: 30px; } .rock { border-radius: 20px; height: 150px; width: 200px; border: 2px solid red; display: flex; align-items: center; justify-content: center; transition: transform 0.05s; } .rock:hover { cursor: pointer; transform: scale(1.05); } .paper { border-radius: 20px; height: 150px; width: 200px; border: 2px solid red; display: flex; align-items: center; justify-content: center; transition: transform 0.05s; } .paper:hover { cursor: pointer; transform: scale(1.05); } .scissors { border-radius: 20px; height: 150px; width: 200px; border: 2px solid red; display: flex; align-items: center; justify-content: center; transition: transform 0.05s; } .scissors:hover { cursor: pointer; transform: scale(1.05); } span { font-size: 22px; } .one { position: relative; top: 40px; } .two { position: relative; top: 60px; } .three { position: relative; top: 80px; font-size: 23px; } .waitdiv { display: flex; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } .div1 { opacity: 0; font-size: 75px; } .div2 { opacity: 0; font-size: 75px; } .div3 { opacity: 0; font-size: 75px; } .container-shoot { height: 100vh; text-align: center; position: relative; } .shoot { font-size: 80px; position: relative; top: 50px; } .round { position: relative; top: 55px; } .versus { display: flex; text-align: center; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 50px; width: 80%; } .v { display: flex; text-align: center; flex-basis: 100%; justify-content: space-evenly; align-items: center; } .choice { border-radius: 20px; text-align: center; border: 2px solid red; /* font-size: 30px; */ height: 100px; display: flex; align-items: center; } .info { position: absolute; bottom: 150px; left: 50%; transform: translate(-50%, -70px); } .info h3 span { color: white; } .score { position: absolute; bottom: 20px; left: 50%; transform: translate(-50%, -20px); } .score span { font-size: 70px; } .container1 { height: 100vh; position: relative; } .play-btn { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); padding: 15px 30px; cursor: pointer; color: black; font-size: 16px; border-radius: 12px; border: none; } .next { border-radius: 17px; border: none; position: absolute; left: 90%; top: 90%; transform: translate(-50%, -50%); cursor: pointer; padding: 12px 18px; color: black; }
 <div class="container1"> <button class="play-btn">PLAY</button> </div>

I made a rock paper scissors game with javascript and I'm having trouble with keeping score. I need a way to keep track of who is winning between the player and the computer, that score should be displayed right at the bottom of the page. If you run the whole code(html, css and javascript), you will see this example right at the bottom of the last page I encourage you to please run the whole code

Here's my HTML file:

<div class="container1"><button class="play-btn">PLAY</button></div>

Here's the code i wrote in my JAVASCRIPT file:

function computerPlay() {
let [min, max] = [1, 3]
let randomNumber =  Math.floor(Math.random() * (max - min + 1)) + min;
if(randomNumber == 1) return 'ROCK'
else if(randomNumber == 2) return 'PAPER'
else return 'SCISSORS'

}

function play(playerSelection, computerSelection) {
let move = playerSelection;
  let com = computerSelection;
  if(move == 'ROCK' && com == 'SCISSORS') return 'ROCK beats SCISSORS';
  else if(move == 'ROCK' && com == 'PAPER') return 'PAPER beats ROCK'
  else if(move == 'SCISSORS' && com == 'ROCK') return 'ROCK beats SCISSORS'
  else if(move == 'SCISSORS' && com == 'PAPER') return 'SCISSORS beat PAPER'
  else if(move == 'PAPER' && com == 'SCISSORS') return 'SCISSORS beat PAPER'
  else if(move == 'PAPER' && com == 'ROCK') return 'PAPER beats ROCK'
  else if(move == com) return 'DRAW'

}

let arr = [];

let playBtn = document.querySelector('.play-btn');
let container1 = document.querySelector('.container1');
playBtn.addEventListener('click', makeContainer);

This is the function that creates the page that needs the player's input(rock, paper or scissors)

function makeContainer() {

  container1.remove();

  let con = document.createElement('div');
  con.classList.add('container');
  let h1 = document.createElement('h1');
  h1.classList.add('one');
  h1.textContent = 'ROCK PAPER SCISSORS';
  let h12 = document.createElement('h1');
  h12.classList.add('two');
  h12.textContent = 'ROUND 1';
  let h13 = document.createElement('h1');
  h13.classList.add('three');
  h13.textContent = 'MAKE YOUR MOVE';

  let buttons = document.createElement('div');
  buttons.classList.add('buttons');

  let btn1 = document.createElement('div');
  btn1.classList.add('rock');
  let span = document.createElement('span');
  span.textContent = 'ROCK';
  btn1.append(span);

  let btn2 = document.createElement('div');
  btn2.classList.add('paper');
  let span2 = document.createElement('span');
  span2.textContent = 'PAPER';
  btn2.append(span2);

  let btn3 = document.createElement('div');
  btn3.classList.add('scissors');
  let span3 = document.createElement('span');
  span3.textContent = 'SCISSORS';
  btn3.append(span3);

  buttons.append(btn1, btn2, btn3);

  con.append(h1, h12, h13, buttons);


  document.body.append(con);


  const container = document.querySelector('.container');
  const rock = document.querySelector('.rock');
  const paper = document.querySelector('.paper');
  const scissors = document.querySelector('.scissors');
  [rock, paper, scissors].forEach((c) => c.addEventListener('click', (e) => {
    // console.log(e.target);
    containerDisappear(container, c)
  }));
}

This function removes the makeContainer page(the one that shows rock paper scissors) and adds a transition to it

function containerDisappear(con, r) {
  let choi = r;
  con.style.transitionProperty = 'opacity';
  con.style.transitionDuration = '1s';
  con.style.opacity = '0';
  setTimeout(() => con.remove('container'), 1000); 
  animation(choi);
}

This function displays the animation that pops up after the the makeContainer page has disappeared

 function animation(r) {
  let choic = r;
  const waitdiv = document.createElement('div');
    waitdiv.classList.add('waitdiv');
    const div1 = document.createElement('div');
    const div2 = document.createElement('div');
    const div3 = document.createElement('div');    
    div1.classList.add('div1');
    div2.classList.add('div2');        
    div3.classList.add('div3');
    div1.textContent = 'ROCK...';
    div2.textContent = 'PAPER...';
    div3.textContent = 'SCISSORS...';
    waitdiv.append(div1, div2, div3);
    document.body.append(waitdiv);    
  
    setTimeout(() => {
        div1.style.transitionProperty = 'opacity';
        div1.style.transitionDuration = '.6s';
        div1.style.opacity = '1';
    }, 600);
  
    setTimeout(() => {
        div2.style.transitionProperty = 'opacity';
        div2.style.transitionDuration = '.6s';
        div2.style.opacity = '1';
    }, 1200);
  
    setTimeout(() => {
        div3.style.transitionProperty = 'opacity';
        div3.style.transitionDuration = '.6s';
        div3.style.opacity = '1';
    }, 1800); 
    
    
    setTimeout(() => {
        waitdiv.style.transitionProperty = 'opacity';
        waitdiv.style.transitionDuration = '.3s';
        waitdiv.style.opacity = '0';
        waitdiv.remove();
    }, 2400);
    
    setTimeout(() => {
      results(choic)
    }, 2400);
}

This function displays the player's move vs the computer's move and then displays information about who lost Theres a 0:1 right at the bottom of this page, it's static, it doesn't update after each move, it's actually one of the things I'm struggling with

function results(c) {
  const cShoot = document.createElement('div');
    cShoot.classList.add('container-shoot');
    const shoot = document.createElement('h1');
    shoot.classList.add('shoot');
    const round = document.createElement('h1');
    round.classList.add('round');
    const versus = document.createElement('div');
    versus.classList.add('versus');
    const v = document.createElement('div');
    v.classList.add('v');
    const h6 = document.createElement('h6');
    const choice = document.createElement('div');
    choice.classList.add('choice');
    const vs = document.createElement('div');
    vs.classList.add('v');
    const v2 = document.createElement('div');
    v2.classList.add('v');
    const choice2 = document.createElement('div');
    choice2.classList.add('choice');
    const h62 = document.createElement('h6');
  
    // ----------------second part---------------------------------------
    const info = document.createElement('div');
    info.classList.add('info');
    const h2 = document.createElement('h2');
    const h3 = document.createElement('h3');
    const span = document.createElement('span');
  
  
    // ---------------------third part------------------------------------
    const score = document.createElement('div');
    score.classList.add('score');
    const span2 = document.createElement('span');
    span2.classList.add('player');
    const span3 = document.createElement('span');
    span3.classList.add('colon');
    const span4 = document.createElement('span');
    span4.classList.add('com');


    // ---------------------time to append stuff--------------------------------------------
    cShoot.append(shoot, round, versus, info, score);
    versus.append(v, vs, v2);
    v.append(h6, choice);
    vs.textContent = 'VS';
    v2.append(choice2, h62);
    info.append(h2, h3);
    h3.append(span);
    span2.textContent = '0';
    span3.textContent = ':';
    span4.textContent = '1';
    score.append(span2, span3, span4);
  
    // ----------------adding text--------------------------------------------
    shoot.textContent = 'SHOOT!!!';
    round.textContent = 'ROUND 1';
    h6.textContent = 'YOU';
    choice.textContent = (c.classList.value == 'rock') ? 'ROCK' :
    c.classList.value == 'paper' ? 'PAPER' : 
    c.classList.value == 'scissors' ? 'SCISSORS' : null;
    vs.textContent = 'VS';
    choice2.textContent = computerPlay();
    h62.textContent = 'COM';
    h2.textContent = play(choice.textContent, choice2.textContent);
    span.textContent = s();
    if(span.textContent == 'YOU WIN THIS ROUND') span.style.color = 'green';
    else span.style.color = 'red'

    // -------------------------function-------------------------------------------------
    function s() {
      if(choice.textContent == 'ROCK' && choice2.textContent == 'SCISSORS') {
        return 'YOU WIN THIS ROUND'
      }
      else if(choice.textContent == 'ROCK' && choice2.textContent == 'PAPER') {
        return 'YOU LOSE THIS ROUND'
      }
      else if(choice.textContent == 'SCISSORS' && choice2.textContent == 'ROCK') {
        return 'YOU LOSE THIS ROUND'
      }
      else if(choice.textContent == 'SCISSORS' && choice2.textContent == 'PAPER') {
        return 'YOU WIN THIS ROUND'
      }
      else if(choice.textContent == 'PAPER' && choice2.textContent == 'SCISSORS') {
        return 'YOU LOSE THIS ROUND'
      }
      else if(choice.textContent == 'PAPER' && choice2.textContent == 'ROCK') {
        return 'YOU WIN THIS ROUND'
      }
    }
    // --------------------------------------------------------------------------


    document.body.append(cShoot);
    // cShoot is the first variable that was created inside this function, it's the div tha holds everything on this page


}

Here's my css file:

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    color: white;
}

body {
    background-color: #333;
}

.container {
    height: 100vh;
    text-align: center;
    position: relative;
    opacity: 1;
}

.buttons {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    column-gap: 30px;
}

.rock {
    border-radius: 20px;
    height: 150px;
    width: 200px;
    border: 2px solid red;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.05s;
}

.rock:hover {
    cursor: pointer;
    transform: scale(1.05);
}

.paper {
    border-radius: 20px;
    height: 150px;
    width: 200px;
    border: 2px solid red;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.05s;
}

.paper:hover {
    cursor: pointer;
    transform: scale(1.05);
}

.scissors {
    border-radius: 20px;
    height: 150px;
    width: 200px;
    border: 2px solid red;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.05s;
}

.scissors:hover {
    cursor: pointer;
    transform: scale(1.05);
}

span {
    font-size: 22px;
}


.one {
    position: relative;
    top: 40px;
}

.two {
    position: relative;
    top: 60px;
}

.three {
    position: relative;
    top: 80px;
    font-size: 23px;
}

.waitdiv {
    display: flex;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}


.div1 {
    opacity: 0;
    font-size: 75px;
}

.div2 {
    opacity: 0;
    font-size: 75px;
}

.div3 {
    opacity: 0;
    font-size: 75px;
}

.container-shoot {
    height: 100vh;
    text-align: center;
    position: relative;
}

.shoot {
    font-size: 80px;
    position: relative;
    top: 50px;
}

.round {
    position: relative;
    top: 55px;
}

.versus {
    display: flex;
    text-align: center;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 50px;
    width: 80%;
}

.v {
    display: flex;
    text-align: center;
    flex-basis: 100%;
    justify-content: space-evenly;
    align-items: center;
}

.choice {
    border-radius: 20px;
    text-align: center;
    border: 2px solid red;
    /* font-size: 30px; */
    height: 100px;
    display: flex;
    align-items: center;
}

.info {
    position: absolute;
    bottom: 150px;
    left: 50%;
    transform: translate(-50%, -70px);
}

.info h3 span {
    color: white;
}

.score {
    position: absolute;
    bottom: 20px;
    left: 50%;
    transform: translate(-50%, -20px); 
}

.score span {
    font-size: 70px;
}

.container1 {
    height: 100vh;
    position: relative;
}

.play-btn {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    padding: 15px 30px;
    cursor: pointer;
    color: black;
    font-size: 16px;
    border-radius: 12px;
    border: none;
}

.next {
    border-radius: 17px;
    border: none;
    position: absolute;
    left: 90%;
    top: 90%;
    transform: translate(-50%, -50%);
    cursor: pointer;
    padding: 12px 18px;
    color: black;

}

Problem

"...I'm having trouble with keeping score. I need a way to keep track of who is winning between the player and the computer,..."

I cannot be specifically say what the problem is in OP ( O riginal P ost) code because it's too bloated. Instead of combing through 200 lines and ending up rewriting 80% of the code, I have made a roshambo game that behaves and appears simular to the OP code (see Example B ).

Solutions

<form> & Form Controls

The best HTML layout for simple games is a <form> and form controls . The HTMLFormElement and HTMLFormControlsCollection interfaces allow us to use a terse and versatile syntax (see Figure IA and Figure IB )

Figure IA - Simple HTML layout of <form> and form controls

<form id='contacts'>
  <fieldset name='group'>
    <label>First Name:
      <input id='firstname' value='zer0'>
    </label>
    <label>Last Name:
      <input id='lastname' value='0ne'>
    </label>
  </fieldset>
  <fieldset name='group'>
    <output id='fullname'></output>
  </fieldset>
  <fieldset name='group'>
    <label>Phone: <input id='phone' type='tel'></label>
    <button type='reset'>Reset</button>
    <button>Submit</button>
  </fieldset>
</form>

Figure IB - A comparison between DOM interfaces

Objective HTMLFormElement Common DOM Methods
<form> const C = document.forms.contacts const C = document.getElementById('contacts')
All form controls const all = C.elements const all = C.querySelectorAll('fieldset, input, button')
All <fieldset> s const sets = all.group const sets = C.querySelectorAll('fieldset')
Get the value of <input id='phone'> let cell = all.phone.value let cell = C.querySelector('#phone').value

Also see Form Properties and Methods

Special Events

There are also events that are made exclusively for <form> s and form controls (see Figure II ). Specialized behavior allows us to write less and control which elements can react and which elements to exclude. Moreover, it's important to know how to delegate events by binding events to a parent or ancestor element of multiple origin elements (buttons, inputs, etc) and writing event handlers that target specific elements.

Figure II - Special Events

Event Tags Trigger Behavior
submit <form> 1. User is focused on a text field and hits the Enter/Return key.
2. User clicks a <button> , <input type='submit'> , or <input type='image'> .
3. .submit() method.
<form> will send the values of all form controls that have a [name] attribute to a server. If there is no server then it will return a blank page.
reset <form> 1. User clicks a button with type="reset"
2. .reset() method
All form control values entered by the user are removed
change <form> and form controls User enters data or selects a value on/from a form control then loses focus
input <form> and form controls User enters data or selects a value on/from a form control

✳ buttons: <button> with or without type : "button" , "submit" , "reset" , and <input> with one of the following type : "button" , "submit" , "reset" , "image"
❉ buttons and <output> are excluded

Incrementing .value Property and Closures - See Example A

  1. Define a variable at initial number (usually 0) outside of any function.
  2. Reference a form control that has or can have a .value property.
  3. Increment the variable from #1.
  4. Assign the value of the variable from #1 to the referenced form control from #2

In #1 we define a variable (it can be a number, an index of an array or an object value from a property, etc) outside of the function because once a function ends, everything within is garbage collected, so the value must be outside but within scope of the function, see Closures .

Details are commented in both Example A and Example B

Example A

 // Define values outside of function #1 const coin = { sides: ['https://i.ibb.co/QvT4L5k/heads.png', 'https://i.ibb.co/C6Y3HKd/tails.png'], heads: 0, tails: 0 }; // Reference the <form> const UI = document.forms.toss; // Prevent normal <form> behavior during a submit event UI.onsubmit = e => e.preventDefault(); // Bind <form> to click event UI.onclick = flipCoin; // Event handler passes Event Object by default function flipCoin(e) { // Get a random number between 0 and 1 let side = Math.random() < 0.5 ? 0 : 1; // 0 or 1 // Reference the element the user clicked const clk = e.target; // Reference all form controls const IO = this.elements; /* If the user clicked input#flip... ...change it's src... ...increment coin = {heads or tails}... ...assign heads/tails value of {coin} to the <output>s */ if (clk.id === 'flip') { clk.src = coin.sides[side]; side === 0 ? coin.heads += 1 : coin.tails += 1; IO.heads.value = coin.heads; IO.tails.value = coin.tails; } }
 <form id='toss'> <input id='flip' src='https://i.ibb.co/QvT4L5k/heads.png' type='image'><br> Heads: <output id='heads'></output><br> Tails: <output id='tails'></output> </form>

Example B

 // Reference <form> const game = document.forms.roshambo; // Collect all <dialog> into an array const dialogs = [...document.querySelectorAll('dialog')]; // Define an object outside of functions to keep track of the score const score = { turn: 0, wins: 0, lost: 0, draw: 0 }; /* Bind the "DOMContentLoaded" event to the document When all DOM content is loaded... ...close all <dialog>s... ...open the first <dialog> */ document.addEventListener('DOMContentLoaded', function() { dialogs.forEach(d => d.close()); dialogs[0].showModal(); }) // Bind "reset" event to <form> game.onreset = phase0; // Bind "click" event to <form> game.onclick = choice; // Event handler passes Event Object by default function choice(event) { // Reference the tag the user clicked const clicked = event.target; // Reference all form controls const IO = this.elements; /* If the user clicked a [name="clear"]... ...reset all of {score}'s properties to 0... ...trigger a "reset" event on <form> */ if (clicked.name === 'clear') { for (let prop in score) { score[prop] = 0; } this.reset(); } /* If the user clicked a [name="rps"]... ...close all <dialog>... ...open the third <dialog>... ...define an array - index 0 is the value of the clicked <button> converted into a number index 1 is the result of rand() [(0-2), (0-2)]... ...call phase2() passing the array and a reference to all form controls */ if (clicked.name === 'rps') { dialogs.forEach(d => d.close()); dialogs[2].showModal(); let RPS = [parseInt(clicked.value), rand()]; phase2(RPS, IO); } } // Event handler passes the Event Object by default function phase0(event) { // Prevent the <form> from clearing out all of the <output> event.preventDefault(); // Reference all form controls const IO = this.elements; // Close all <dialog>s dialogs.forEach(d => d.close()); // Open the second <dialog> dialogs[1].showModal(); // Increment score: {turn} score.turn += 1; // call phase1() passing the reference to all form controls phase1(IO); } // Pass the reference to all form controls function phase1(IO) { // Reference all form controls in fieldset#choices const io = IO.choices.elements; // Update all <output> under fieldset#choices io.round.value = score.turn; io.wins.value = score.wins; io.lost.value = score.lost; io.draw.value = score.draw; } // Pass the array of numbers and the reference to all form controls function phase2(RPS, IO) { // Define an array of strings const text = ['ROCK..., ', 'PAPER..., ', 'SCISSORS... ']; // Define a number that will be the base amount of ms for timeouts let time = 600; // Call animate() passing array, a selector of tag to append to, and time animate(text, '#animation h1', time); // Call phase3() passing what phase2() passed on the calculated time setTimeout(() => { phase3(RPS, IO); }, (text.length + 4) * time); } // Pass array and reference function phase3(RPS, IO) { // Close all <dialog>s dialogs.forEach(d => d.close()); // Open the fourth <dialog> dialogs[3].showModal(); // Call outcome() passing the array and reference outcome(RPS, IO); } // Displays 'ROCK..., ', 'PAPER..., ', 'SCISSORS... ' at timed intervals function delay(array, title, time) { array.forEach((segment, index) => { setTimeout(() => { const tag = document.createElement('b'); tag.textContent = segment; tag.className = 'fadeIn'; title.append(tag); }, index * time); }); } // Runs delay() and animates "GO!" function animate(array, selector, time = 1000) { const title = document.querySelector(selector); delay(array, title, time); setTimeout(() => { title.replaceChildren(); title.insertAdjacentHTML('beforeend', `<b class='zoom'>GO!</b>`); }, (array.length + 1) * time); setTimeout(() => { title.className = 'fadeOut'; title.replaceChildren(); }, (array.length + 3) * time); title.className = ''; } // Returns a random number in the range of 0-2 function rand() { return Math.floor(Math.random() * 2) + 1; } // Pass the numbers derived from choice(e) function play(pick, comp) { // This is a ternary expression - an abbreviated if/else statement return pick === comp // if user's num equals cpu's num ? 0 // return 0 : comp === pick - 1 // if cpu's num is 1 less than user's num ? 1 // return 1 : comp === 2 && pick === 0 // if cpu num is 2 AND user's num is 0 ? 1 // return 1 : -1; // else return -1 } // Pass the array and reference function outcome(RPS, IO) { // Define an array of RPS const played = ['🪨 Rock', '🧻 Paper', '✂️ Scissors']; // Reference all form controls under fieldset#outcome const io = IO.outcome.elements; // Get the return of play() passing the two numbers of the given array let wld = play(RPS[0], RPS[1]); // Assign values to the <output>s io.you.value = played[RPS[0]]; io.cpu.value = played[RPS[1]]; io.round.value = score.turn; io.draw.value = score.draw; io.wins.value = score.wins; io.lost.value = score.lost; // Determine what will be displayed by the return of play() switch (wld) { case 0: score.draw += 1; io.draw.value = score.draw; io.message.value = "It's a Draw"; io.vs.value = "Ties with"; break; case 1: score.wins += 1; io.wins.value = score.wins; io.message.value = "You Win"; io.vs.value = "Beats"; break; case -1: score.lost += 1; io.lost.value = score.lost; io.message.value = "You Lose"; io.vs.value = "is Beaten by"; break; default: break; } }
 @import url('https://fonts.googleapis.com/css2?family=Oswald:wght@300&family=Raleway:wght@500&display=swap'); @keyframes click { 0% { transform: scale(1.0); } 50% { transform: scale(0.9); } 100% { transform: scale(1.0); } } @keyframes fadeIn { 0% { opacity: 0; } 100% { opacity: 1; } } @keyframes fadeOut { 0% { opacity: 1; } 100% { opacity: 0; } } @keyframes zoom { 0% { transform: scale(1); } 100% { transform: scale(4); } } * { margin: 0; padding: 0; box-sizing: border-box; } html, body { height: 100%; } html { font: 300 4vmin/1 Oswald; } body { background-color: #333; color: #fff; } form { position: relative; min-height: 100%; } dialog { position: absolute; top: 20%; left: 50%; display: flex; flex-flow: column nowrap; justify-content: center; align-items: center; min-height: 50vh; border-color: transparent; background-color: #333; transform: translate(-50%); overflow: hidden; } dialog::backdrop { background-color: #333; } .phase { display: flex; flex-flow: column nowrap; justify-content: center; align-items: center; gap: 1rem; min-width: 70vw; padding: 1rem; border-color: transparent; color: #fff; } .buttons { display: flex; flex-flow: row nowrap; justify-content: space-around; align-items: center; gap: 1rem; padding: 1rem; border-color: transparent; } legend { display: flex; flex-flow: column nowrap; justify-content: center; align-items: center; gap: 1rem; margin-left: 50%; padding: 1rem; color: #fff; transform: translateX(-50%); } h1, h2, h3 { font-family: Raleway; white-space: nowrap; } h1 { font-size: 2.5rem; } h2 { font-size: 2.25rem; } h3 { font-size: 1.75rem; } .score { display: flex; justify-content: space-evenly; align-items: center; min-width: 100%; } output, b { display: inline-block; } output::after { content: attr(value); } .wins::before { content: 'Won '; } .lost::before { content: 'Lost '; } .draw::before { content: 'Draw '; } button { display: inline-flex; flex-flow: row nowrap; justify-content: center; align-items: center; height: 4rem; width: 10rem; border: 0.2rem solid red; border-radius: 2rem; color: #fff; font: inherit; font-size: 2rem; font-variant: small-caps; background-color: #333; cursor: pointer; } button:hover { background-color: #fff; color: red; } button:active { animation: click 0.3s forwards; } button:focus { outline: 0; } .fadeIn { animation: fadeIn 0.6s ease-out; } .fadeOut { animation: fadeOut 0.6s ease-in; } .zoom { animation: zoom 0.5s ease-out forwards; } .number { font-family: Consolas; }
 <form id="roshambo"> <dialog> <fieldset id='start' class='phase'> <button name='continue' type="reset">Play</button> </fieldset> </dialog> <dialog> <fieldset id='choices' class='phase'> <legend> <h1>Rock, Paper, Scissors</h1> <h2>Round <output name='round' class='number'></output> </h2> <h3>Make Your Move</h3> <h3 class='score'> <b class='wins'> <output name='wins' class='number'></output> </b> <b class='lost'> <output name='lost' class='number'></output> </b> <b class='draw'> <output name='draw' class='number'></output> </b> </h3> </legend> <fieldset class='buttons'> <button name='rps' value='0' type='button'>🪨 Rock</button> <button name='rps' value='1' type='button'>🧻 Paper</button> <button name='rps' value='2' type='button'>✂️ Scissors</button> </fieldset> </fieldset> </dialog> <dialog> <fieldset id='animation' class='phase'> <legend> <h1></h1> </legend> </fieldset> </dialog> <dialog> <fieldset id='outcome' class='phase'> <legend> <h1><output id='message'></output></h1> <h2>Round <output name='round' class='number'></output></h2> <h3>Your <output id='you'></output> <output id='vs'></output> Your Opponent's <output id='cpu'></output> </h3> <h3 class='score'> <b class='wins'> <output name='wins' class='number'></output> </b> <b class='lost'> <output name='lost' class='number'></output> </b> <b class='draw'> <output name='draw' class='number'></output> </b> </h3> </legend> <fieldset class='buttons'> <button name='continue' type='reset'>Continue</button> <button name='clear' type='reset'>Clear</button> </fieldset> </fieldset> </dialog> </form>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM