简体   繁体   中英

JS - If one element gets a class toggled, the other elements should be able to get the class toggled

I am making a rock paper scissor game, and I only want the user to be able to pick one choice,

Basically whenever I toggle option-list-clicked, the other options should not be able to get toggled whenever they are clicked, since I want the user to only be able to pick one choice.

Second thing is, how do i go about checking which element the user picked, I wanna store it into a let, but do i have to check which element got that specific class (option-list-clicked) toggled

 let randomNumber = Math.floor(Math.random() * 3) + 1; let optionLists = document.querySelectorAll(".option-list"); let optionListText = document.querySelectorAll(".option-list-text"); let start = 0; let words = ["paper", "scissors", "rock"]; let randomWord = words[randomNumber]; document.addEventListener("keypress", () => { start = 0; document.getElementById("starting-title").className = "hidden"; document.getElementById("game-question").className = "game-question"; document.getElementById("button").className = "button"; optionLists.forEach((optionList) => { optionList.className = "option-list"; }); }); optionListText.forEach((option) => { option.addEventListener("click", () => { option.classList.toggle("option-list-clicked"); }); }); 
 * { outline: 0; } html { font-size: 62.5%; box-sizing: border-box; } body { margin: 0; padding: 0; font-family: cursive; background: lightgrey; } .starting-title { position: absolute; top: 20%; text-transform: uppercase; left: 35%; font-weight: bold; letter-spacing: .2rem; text-shadow: 0rem .3rem .5rem black; font-size: 4rem; } .ending-title { position: absolute; top: 20%; text-transform: uppercase; left: 35%; font-weight: bold; letter-spacing: .2rem; text-shadow: 0rem .3rem .5rem black; font-size: 4rem; } .hidden { visibility: hidden; } .game-question { position: absolute; top: 20%; text-transform: uppercase; left: 35%; font-weight: bold; letter-spacing: .2rem; text-shadow: 0rem .3rem .5rem black; font-size: 4rem; } .options { display: flex; flex-direction: row; flex: 1 1 1; position: absolute; top: 50%; left: 36%; } .option-list { margin: 2rem 4rem; list-style: none; text-decoration: none; } .option-list-text { font-size: 2rem; font-weight: bold; letter-spacing: .2rem; text-transform: uppercase; text-shadow: 0rem .3rem .7rem black; cursor: pointer; } .option-list-clicked { padding: 2rem; border-radius: 1rem; background: blue; } .button { position: absolute; top: 70%; left: 47.5%; border: 0; font-size: 1.3rem; cursor: pointer; font-weight: bold; padding: 1.3rem; border-radius: 1rem; background: linear-gradient(to bottom right, rgba(0, 255, 255, 0.596), rgba(0, 0, 255, 0.616), rgba(0, 0, 0, 0.623)); } 
 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" href="/style.css"> <title>RoPapSis</title> </head> <body> <h1 id="starting-title" class="starting-title">Press Any Key To Start</h1> <h1 id="ending-title" class="ending-title hidden"></h1> <h1 id="game-question" class="game-question hidden">Rock, Paper or Scissors</h1> <ul id="options" class="options"> <li id="option-list" class="option-list hidden"> <p id="scissors" id="option-list-text scissors" class="option-list-text">scissors</p> </li> <li id="option-list" class="option-list hidden"> <p id="paper" id="option-list-text paper" class="option-list-text">Paper</p> </li> <li id="option-list" class="option-list hidden"> <p id="rock" id="option-list-text rock" class="option-list-text">Rock</p> </li> </ul> <button id="button" class="button hidden">Submit Your Choice</button> <script src="/main.js"></script> </body> </html> 

First point is that the ID of an element should be unique in whole document.So we must change li and p tags id's to a proper state.For example:

<p id="scissors" id="option-list-text scissors" class="option-list-text">scissors</p>

// can be be written as :

<p id="scissors" class="option-list-text">scissors</p>

To make just one item selectable , just assign option-list-clicked class to clicked and remove it from other elements.Like so:

let selected_id = '';
optionListText.forEach((option) => {
    option.addEventListener("click", () => {
        option.classList.toggle("option-list-clicked");
        selected_id = option.getAttribute('id');
        let NotSelecteds=document.querySelectorAll(".option-list-text:not(#"+selected_id+")")
        NotSelecteds.forEach((option1) => {
           option1.classList.remove('option-list-clicked');
        });
    });
});

Notice that selected_id in the code above is the answer for your second question.

Here's a modified version that handles both issues (in the clickListener function.) See the in-code comments for clarification (or ask if something is still unclear). It's up to you to decide what else should happen when the button is clicked.

The only problem in your original code is the way the id attribute is used. (One html element can only have one id , and no html element can have the same value for its id attribute as another html element on the same page.) This version resolves that problem, removes some redundancies, and generally simplifies things.

 // Global identifiers const playerOptions = document.getElementsByTagName("LI"); const computerOptionsArray = ["paper", "scissors", "rock"]; let computerSelection, playerSelection; // Listeners document.addEventListener("keyup", startGame); document.addEventListener("click", clickListener); // Functions function startGame(){ // Hides #starting-title and shows everything else document.getElementById("starting-title").classList.add("hidden"); document.getElementById("game-question").classList.remove("hidden"); document.getElementById("button").classList.remove("hidden"); Array.from(playerOptions).forEach( (li) => { li.classList.remove("hidden"); } ); // Randomizes computerSelection let randomZeroOneOrTwo = Math.floor(Math.random() * 3); // No need to add 1 computerSelection = computerOptionsArray[randomZeroOneOrTwo]; // Clears playerSelection playerSelection = null; } function clickListener(event){ // When user clicks an LI element, if `playerSelection` is empty, this function highlights the // clicked element, and assign the value of its `id` attribute to `playerSelection` Array.from(playerOptions).forEach( (li) => { if(li == event.target){ // If click was on an "LI", remember its `id` attribute's value if(playerSelection){ return; } // End function here if player already chose event.target.classList.add("selected"); // Highlight the clicked LI playerSelection = event.target.id; // Store the players selection } }); if(event.target.id == "button"){ // Respond to clicks on the button here // Logs the selections console.log(`player chose ${playerSelection}, computer chose ${computerSelection}`); // Maybe change this to something like: // If playerSelection is not empty... // compare it to computerSelection, announce result, and reset game } } 
 * { outline: 0; } html { font-size: 62.5%; box-sizing: border-box; } body { margin: 0; padding: 0; font-family: cursive; background: lightgrey; } button { margin-left: 24rem; border: 0; font-size: 1.3rem; cursor: pointer; font-weight: bold; padding: 1.3rem; border-radius: 1rem; background: linear-gradient(to bottom right, rgba(0, 255, 255, 0.596), rgba(0, 0, 255, 0.616), rgba(0, 0, 0, 0.623)); } ul { display: flex; flex-direction: row; flex: 1 1 1; margin-left: 6rem; } li { margin: 1rem; list-style: none; text-decoration: none; font-size: 2rem; padding: 1rem; font-weight: bold; letter-spacing: .2rem; text-transform: uppercase; text-shadow: 0rem .3rem .7rem black; cursor: pointer; } .hidden { visibility: hidden; } .selected { border-radius: 1rem; background: blue; } .title { margin-left: 6rem; text-transform: uppercase; font-weight: bold; letter-spacing: .2rem; text-shadow: 0rem .3rem .5rem black; font-size: 3rem; } 
 <!DOCTYPE html> <html> <head></head> <body> <h1 id="starting-title" class="title">Press Any Key To Start</h1> <h1 id="game-question" class="title hidden">Rock, Paper or Scissors</h1> <ul> <li id="scissors" class="hidden">Scissors</li> <li id="paper" class="hidden">Paper</li> <li id="rock" class="hidden">Rock</li> </ul> <button id="button" class="hidden">Submit Your Choice</button> </body> </html> 

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