I am doing a project on paper-rock-scissor that has UI. So, I have four buttons, Start game, rock, paper and scissor. Previously I write the code separately and it works. But right now because I want the result from clicking the button to be an input to another function. So I tried to group all the buttons altogether in my code below. However, it seems like the button doesnt seem to work but there are no errors. I have no idea why? Below are my code :
------------- HTML ---------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Project Rock Paper Scissors</title>
<script src = "javascript.js" defer> </script>
</head>
<body>
<div >
<button id="startgame"> Start game </button>
<button id="rock"> Rock </button>
<button id="paper"> Paper </button>
<button id="scissor"> Scissor </button>
</div>
</body>
</html>
------------ Javascript ---------------
const button = document.querySelector(".btn-group");
const startGame = document.querySelector('#startgame');
const rock = document.querySelector('#rock');
const paper = document.querySelector('#paper');
const scissor = document.querySelector('#scissor');
button.addEventListener('click', function(selection) {
if (selection === startGame) {
startGame.addEventListener('click', () => {
alert("Choose Rock, Paper or Scissor");
})
} else if (selection === rock) {
rock.addEventListener('click', () => {
let item = "rock";
return item.toLowerCase();
})
} else if (selection === paper) {
paper.addEventListener('click', () => {
let item2 = "paper";
return item2.toLowerCase();
})
} else if (selection === scissor) {
scissor.addEventListener('click', () => {
let item3 = "scissor";
return item3.toLowerCase();
})
}
})
----------- Js code above to be used as argument to function playRound(.... , ....) below ------------
function playRound(playerSelection, computerSelection) {
if (playerSelection === "Paper".toLowerCase() && computerSelection.toLowerCase() === "Rock".toLowerCase() ) {
console.log(`Player choose ${playerSelection} and computer plays ${computerSelection} player wins !`);
} else if (playerSelection === "Scissor".toLowerCase() && computerSelection.toLowerCase() === "Paper".toLowerCase() ) {
console.log(`Player choose ${playerSelection} and computer plays ${computerSelection} player wins !`);
} else if (playerSelection === "Rock".toLowerCase() && computerSelection.toLowerCase() === "Scissor".toLowerCase() ) {
console.log(`Player choose ${playerSelection} and computer plays ${computerSelection} player wins !`);
} else if (playerSelection === computerSelection.toLowerCase() ) {
console.log(`Player choose ${playerSelection} and computer plays ${computerSelection} game is draw !`);
} else {
console.log(`Player choose ${playerSelection}, computer plays ${computerSelection}, computer wins !`);
}
}
CodePudding user response:
you have a bug in your code where selection
is an event object, and not the element which generated the event:
button.addEventListener('click', function(selection) { ...
Your if
statements are comparing selection
(the event object) to strongly equal the elements that were clicked, which is where it is getting skipped. On the event object selection
you'll find the target
property: see https://developer.mozilla.org/en-US/docs/Web/API/Event/target
So you might write your if statments this way:
if ( selection.target == startgame ) { ....
CodePudding user response:
There are a few of issues there:
You're waiting until a click occurs anywhere within
.btn-group
before you add click handlers to the buttons themselves. That doesn't make any sense. You would either use an overall click handler on.btn-group
and use event delegation to determine what button was pressed, or use event handlers on the individual buttons (probably simpler in this specific case).An event handler receives an event object, not an element, so
selection
will never matchstartgame
or any of the others. The event object'starget
property refers to the element where the event was targeted, so with your markup that would match one of your buttons (but beware that if you had<button><strong>xyz</strong></button>
, it would be thestrong
element, not thebutton
element, so you'd have to handle that, perhaps withclosest
).You're returning
item.toString()
from your inner event handlers, but that doesn't do anything useful. The return value from anaddEventListener
event handler is completely ignored.
The simple way to fix #1 and #2 is (in this case) to remove the .btn-group
handler entirely and just hook up the buttons directly. To fix #3, you have to provide yourself some way of showing that information in the DOM. There are dozens of ways of doing that, so I won't go into specifics here, but you can't just return it and have anything useful happen.
CodePudding user response:
If you want to add events when .btn-group
is clicked:
const button = document.querySelector(".btn-group");
const startGame = document.querySelector('#startgame');
const rock = document.querySelector('#rock');
const paper = document.querySelector('#paper');
const scissor = document.querySelector('#scissor');
function addEvents(){
startGame.addEventListener('click', () => {
alert("Choose Rock, Paper or Scissor");
})
rock.addEventListener('click', () => {
let item = "rock";
return item.toLowerCase();
})
paper.addEventListener('click', () => {
let item2 = "paper";
return item2.toLowerCase();
})
scissor.addEventListener('click', () => {
let item3 = "scissor";
return item3.toLowerCase();
})
}
button.addEventListener('click', addEvents)