简体   繁体   中英

How to update a progress bar's value using JavaScript?

So what I'm trying to do is visually lower the health bar using a progress bar depending on certain conditions.

 const bgURLs = { "Air": "https://media1.giphy.com/media/RK7pdHVS4N7he/source.gif", "Fire": "https://i.gifer.com/5NOX.gif", "Water": "https://steamuserimages-a.akamaihd.net/ugc/947328402825377319/20625B881E545FF98AF1A48BAC52D4CBD207101B/", }; let options = document.getElementById("Options") let computerChoice = getComputerChoice() let playerChoice = '' let updatePlayerChoice = Options.addEventListener("click", function(e) { playerChoice = e.target.id; return playerChoice }) function getComputerChoice() { const keys = Object.keys(bgURLs); const randomIndex = [Math.floor(Math.random() * keys.length)] const compChoice = keys[randomIndex] return compChoice } // image shows up after clicked function Options.addEventListener("click", function(e) { let tgt = e.target; let player = document.getElementById("Player") let computer = document.getElementById("Computer") if (tgt.classList.contains("element")) { player.style.backgroundImage = 'url(' + bgURLs[tgt.id] + ')'; computer.style.backgroundImage = 'url(' + bgURLs[computerChoice] + ')'; } }) let playerHealth = document.getElementById("player-health").getAttribute("value") let computerHealth = document.getElementById("computer-health").getAttribute("value"); function compareChoices() { if (playerChoice === "Fire" & computerChoice === "Water") { playerHealth -= 25 } else if (playerChoice === "Fire" & computerChoice === "Air") { playerHealth -= 25 } else if (playerChoice === "Fire" & computerChoice === "Fire") { playerHealth -= 25 } }
 <body> <h1>Rock, Paper, Scissors</h1> <h2>Elements Edition</h2> <h3>Choose Your Element</h3> <div id="Options" > <div id="PlayerBar"> <p>Player Health</p> <progress id="player-health" value="100" max="100"> </progress> </div> <div id="Air" class="element" > <p>Air</p> </div> <div id="Fire" class="element" > <p>Fire</p> </div> <div id="Water" class="element" > <p>Water</p> </div> <div id="ComputerBar"> <p>Computer Health</p> <progress id="computer-health" value="100" max="100"> </progress> </div> </div> <div id="Play-Area"> <div id="Player"> </div> <div id="Computer"> </div> </div>

I figured the main problem is my logic with the last function. What my code does is it listens for the playerChoice using an event listener, which then gives me return value I can use to compare answers with the computer choice. This part of the code works for sure. But i can't seem to target the value attribute to update it based on one of those conditions. When I try console.log playerHealth or computerHealth to see if anything happens it still remains at 100, which is the max value I've set it as. Shouldn't my code visually lower the progress bar depending on my conditions?

https://jsfiddle.net/Jbautista1056/bLs0tyef/

I did this a while ago, and shows different bars, basically what you are aiming for. The calculations are there and also the bars are shown in different colors(inline CSS).

 function myMax() { document.myform.num1.value=document.myform.number1.value; document.myform.num3.value=document.myform.number2.value; document.myform.num2.value=document.myform.number3.value; document.myform.num4.value=document.myform.number4.value; document.myform.max1y2.value=Math.max(document.myform.num1.value,document.myform.num2.value); document.myform.max3y4.value=Math.max(document.myform.num3.value,document.myform.num4.value); document.myform.maxAll.value=Math.max(document.myform.max1y2.value,document.myform.max3y4.value); if(isNaN(document.myform.maxAll.value)){alert("Error in page, Probably Not A Number in a Value");return false;} else document.myform.pct1.value=Math.floor((document.myform.num1.value / document.myform.maxAll.value) * 100); document.getElementById("bar1").style.width = document.myform.pct1.value+'%'; document.myform.pct2.value=Math.floor((document.myform.num2.value / document.myform.maxAll.value) * 100); document.getElementById("bar2").style.width = document.myform.pct2.value+'%'; document.myform.pct3.value=Math.floor((document.myform.num3.value / document.myform.maxAll.value) * 100); document.getElementById("bar3").style.width = document.myform.pct3.value+'%'; document.myform.pct4.value=Math.floor((document.myform.num4.value / document.myform.maxAll.value) * 100); document.getElementById("bar4").style.width = document.myform.pct4.value+'%'; } function checkIt(evt) { evt = (evt) ? evt : window.event var charCode = (evt.which) ? evt.which : evt.keyCode if (charCode > 31 && (charCode < 48 || charCode > 57) && (charCode < 46 || charCode > 46 )) {//set for 46 dot. For dash = (charCode < 45 || charCode > 45 ) status = "This field accepts numbers only." return false } status = "" return true }
 <hr style="position:relative;top: -28px;border: 4px solid black;"> <h3 style="width: 50%;background-color:navy;color:white;position:relative;top: -28px;">&nbsp;VALUES: </h3> <b style="position:relative;top: -38px;">Please fill only 3 Values out of 4: </b> <form align="left" name="myform" style="position:relative;top: -40px;"><br> <table align="left" border="1" cellpadding="4" cellspacing="0" width="34%"> <tbody> <tr><th>[Column A]</th> </tr><tr> <!-- Column 1 Row 1 --> <td> <div align="left"><font color="olive"> Value 1 <input name="number1" size="8" maxlength="" tabindex="1" onblur="myMax()" onkeypress="return checkIt(event)" autofocus="" type="tel"><input name="unitA" size="4" value="Unit A" readonly="readonly" type="text"></font></div><font color="olive"> </font></td> </tr> <tr> <!-- Column 1 Row 2 --> <td> <div align="left"><font color="orange">Value 3 </font><input name="number2" size="8" maxlength="" tabindex="3" onblur="myMax()" onkeypress="return checkIt(event)" type="tel"><input name="unitA" size="4" value="Unit A" readonly="readonly" type="text"> <input title="Clear Value 3" type="button" onclick="document.myform.number2.value='';document.myform.number2.focus();return false" value="X"> </div> </td> </tr> </tbody></table> <table align="left" border="0" cellpadding="4" cellspacing="0" height="67" width="5%"> <tbody> <tr> <td> <div style="font-family:arial;font-weight:bold" align="center"><br><br> =</div> </td> </tr> </tbody></table> <table border="1" cellpadding="4" cellspacing="0" width="34%"> <tbody> <tr><th>[Column B]</th> </tr><tr> <!-- Column 2 Row 1 --> <td> <div align="left"><font color="green">Value 2 </font> <input name="number3" size="8" maxlength="" tabindex="2" onblur="myMax()" onkeypress="return checkIt(event)" type="tel"> <input name="unitB" size="4" value="Unit B" readonly="readonly" type="text"> </div> </td> </tr> <tr> <!-- Column 2 Row 2 --> <td> <div align="left"><font color="red">Value 4 <input name="number4" size="8" maxlength="" tabindex="4" onblur="num4.value=this.value;myMax()" onkeypress="return checkIt(event)" type="tel"> <input name="unitB" size="4" value="Unit B" readonly="readonly" type="text"> <input title="Clear Value 4" type="button" onclick="document.myform.number4.value='';document.myform.number4.focus();return false" value="X"> </font></div><font color="red"> </font></td> </tr> </tbody></table> <font color=olive>Value 1 </font><input name=num1 maxlength="" type="text" readonly><input name=pct1 maxlength="" size="4" type="text" readonly>% <div style="position:relative;top: -4px; text-align:none;"> <div style="height: 20px; width: 100%; background-color: #ddd;"> <div id=bar1 style="height: 20px; background-color: olive; width: 0%;" align="left" ></div> </div> <font color=green>Value 2 </font><input name=num2 maxlength="" type="text" readonly><input name=pct2 maxlength="" size="4" type="text" readonly>% <div style="position:relative;top: -4px; height: 20px; width: 100%; background-color: #ddd;"> <div id=bar2 style="height: 20px; background-color: green; width: 0%;" align="left" ></div> <!-- Ruler --> <div style="z-index:50;position: relative;height: 18px; border-top: 2px dashed silver; width: 100%;">0%</div><center style="z-index:20;position:relative;top: -20px;"> 50% </center> <div style="z-index:20;position:relative;top: -38px; text-align:right;">100%</div> <!-- /Ruler --> </div></div> <div style="position:relative;top: 8px; text-align:none;"> Max from 1&2 = <input name=max1y2 maxlength="" type="text" readonly> </div> <br><br> <font color=orange>Value 3 </font><input name=num3 maxlength="" type="text" readonly><input name=pct3 maxlength="" size="4" type="text" readonly>% <div style="position:relative;top: -4px; text-align:none;"> <div style="height: 20px; width: 100%; background-color: #ddd;"> <div id=bar3 style="height: 20px; background-color: orange; width: 0%;" align="left" ></div> </div> <font color=red>Value 4 </font><input name=num4 maxlength="" type="text" readonly><input name=pct4 maxlength="" size="4" type="text" readonly>% <div style="position:relative;top: -4px; height: 20px; width: 100%; background-color: #ddd;"> <div id=bar4 style="height: 20px; background-color: red; width: 0%;" align="left" ></div> <!-- Ruler --> <div style="z-index:50;position: relative;height: 18px; border-top: 2px dashed silver; width: 100%;">0%</div><center style="z-index:20;position:relative;top: -20px;"> 50% </center> <div style="z-index:20;position:relative;top: -38px; text-align:right;">100%</div> <!-- /Ruler --> </div></div> <div style="position:relative;top: 8px; text-align:none;"> Max from 3&4 = <input name=max3y4 maxlength="" type="text" readonly> <br> Max from All <input name=maxAll maxlength="" type="text" readonly></div> <br>

I hope this helps,

Ramon

You have several problems ranging from referring to the wrong variable ( Options , instead of options ) to not actually updating the progress bar values after evaluating the guesses.

You also have a lot of unnecessary code.

Since I'm not sure of what beats what in your game, you'll have to adjust that set of if/else if conditions as well as add more for the computer losing/gaining points. But, for now, if you click on fire or water repeatedly, you'll see some action. The more concise conditions and score adjustments you add, the more responsive the progress bars will be.

See the comments inline below for details:

 const bgURLs = { "Air": "https://media1.giphy.com/media/RK7pdHVS4N7he/source.gif", "Fire": "https://media2.giphy.com/media/AHeTfHgVFPHgs/source.gif", "Water": "https://steamuserimages-a.akamaihd.net/ugc/947328402825377319/20625B881E545FF98AF1A48BAC52D4CBD207101B/" }; // Don't set variables equal to DOM element properties directly // because every time you want a different property, you have to // query the DOM for the same element over and over. Just get a // reference to the element and when you want a property, just // get it from that element reference. let player = document.getElementById("Player"); let computer = document.getElementById("Computer"); let playerProg = document.getElementById("player-health"); let computerProg = document.getElementById("computer-health"); let options = document.getElementById("Options"); // These need to be declared so they can be accessed throughout // the game, but their values won't be known until an event happens let playerChoice = null; let computerChoice = null; let playerHealth = 100; let computerHealth = 100; function getComputerChoice() { let random = Math.floor(Math.random() * Object.keys(bgURLs).length); computerChoice = Object.keys(bgURLs)[random]; return computerChoice; } // You had Options here, but your variable is options options.addEventListener("click", function(e) { if (e.target.classList.contains("element")) { // Set the player choices playerChoice = e.target.id; player.style.backgroundImage = 'url(' + bgURLs[playerChoice] + ')'; computer.style.backgroundImage = 'url(' + bgURLs[getComputerChoice()] + ')'; // Test the results: console.clear(); console.log(playerChoice, computerChoice); // Now update the progress bars compareChoices(); } }) function compareChoices() { // Use && for logical AND short-circuiting // Ensure that scores don't go below 0 or above 100 // Not sure what beats what so you'll have to adjust as needed. if (playerChoice === "Air" && computerChoice === "Fire") { playerHealth = (playerHealth += 25) > 100 ? 100 : playerHealth; computerHealth = (computerHealth -= 25) < 0 ? 0 : computerHealth; } else if (playerChoice === "Air" && computerChoice === "Water") { playerHealth = (playerHealth += 25) > 100 ? 100 : playerHealth; computerHealth = (computerHealth -= 25) < 0 ? 0 : computerHealth; } else if (playerChoice === "Fire" && computerChoice === "Air") { playerHealth = (playerHealth -= 25) < 0 ? 0 : playerHealth; computerHealth = (computerHealth += 25) > 100 ? 100 : computerHealth; } else if (playerChoice === "Fire" && computerChoice === "Water") { playerHealth = (playerHealth -= 25) < 0 ? 0 : playerHealth; computerHealth = (computerHealth += 25) > 100 ? 100 : computerHealth; } else if (playerChoice === "Water" && computerChoice === "Air") { playerHealth = (playerHealth -= 25) < 0 ? 0 : playerHealth; computerHealth = (computerHealth += 25) > 100 ? 100 : computerHealth; } else if (playerChoice === "Water" && computerChoice === "Fire") { playerHealth = (playerHealth += 25) > 100 ? 100 : playerHealth; computerHealth = (computerHealth -= 25) < 0 ? 0 : computerHealth; } // You must update the progress bars from within the function // that changes their values. playerProg.value = playerHealth; computerProg.value = computerHealth; }
 #Player, #Computer { width:100px; height:50px; background-size:contain; background-repeat:no-repeat; margin:5px 0; } .element { cursor:pointer; display:inline; font-weight:bold; } #Play-Area { clear:both; } #Play-Area div { display:inline-block; } #PlayerBar, #ComputerBar { margin:10px 10px; float:left; }
 <p>Choose Your Element</p> <div id="Options" > <div id="Air" class="element">Air</div> <div id="Fire" class="element">Fire</div> <div id="Water" class="element">Water</div> </div> <div id="PlayerBar"> <div>Player Health</div> <progress id="player-health" value="100" max="100"></progress> </div> <div id="ComputerBar"> <div>Computer Health</div> <progress id="computer-health" value="100" max="100"></progress> </div> <div id="Play-Area"> <div id="Player"></div> <div id="Computer"></div> </div>

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