I am making a basic rock paper scissors game. I am making it so when you hover over an option it rises, and when you click it, it should stay in the air, but I am unable to remove the event listener.
<main>
<h2>Choose A Play:</h2>
<div id="rock" onmouseover="hover('rock')" onmouseout="out('rock')" onclick="select('rock')">
Rock
</div>
<div id="paper" onmouseover="hover('paper')" onmouseout="out('paper')" onclick="select('paper')">
Paper
</div>
<div id="scissors" onmouseover="hover('scissors')" onmouseout="out('scissors')" onclick="select('scissors')">
Scissors
</div>
</main>
#rock {
background-color: #252422;
font-size: 25px;
text-align: center;
color: #fffcf2;
height: 100px;
width: 200px;
padding: 25px;
margin-left: 50px;
margin-top: 50px;
float: left;
}
#paper {
background-color: #252422;
font-size: 25px;
text-align: center;
color: #fffcf2;
height: 100px;
width: 200px;
padding: 25px;
margin-left: 50px;
margin-top: 50px;
float: left;
}
#scissors {
background-color: #252422;
font-size: 25px;
text-align: center;
color: #fffcf2;
height: 100px;
width: 200px;
padding: 25px;
margin-top: 50px;
margin-right: 50px;
float: right;
}
let options = ['rock', 'paper', 'scissors'];
function hover(elementId) {
document.getElementById(elementId).style.marginTop = '10px';
}
function out(elementId) {
document.getElementById(elementId).style.marginTop = '50px';
}
function select(elementId) {
document.getElementById(elementId).style.backgroundColor = '#ffba08';
document.getElementById(elementId).style.marginTop = '10px';
let userChoice = options.filter(x => x === elementId);
let userNoPick = options.filter(x => x !== elementId);
revokeListeners(userChoice, userNoPick);
}
function revokeListeners(userSelection, userNoSelection) {
document.getElementById(userSelection).removeEventListener('mouseout', out)
}
I didn't include all of the CSS so it looks a bit funky.
Expected: When a div is clicked it turns yellow then floats in the air.
Result: The event listener does not get deleted and the box drops again.
You can't remove an event listener with removeEventListener
that was not added with addEventListener
(https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener). That being said, don't remove something you might want later.
I've used a data attribute to manage the selected state. Though another thing to consider would be using hiding radio buttons in label
element, which is an inbuilt way of managing mutually exclusive selections
I've also dropped inline listeners to a more modern approach
let options = ['rock', 'paper', 'scissors'];
//use the data attribute as a selector to add event listeners
document.querySelectorAll('[data-status]').forEach(function(el){
//Click
el.addEventListener("click",function(){
this.style.backgroundColor = '#ffba08';
this.style.marginTop = '10px';
this.dataset.status = "selected";
let userChoice = options.filter(x => x === this.id);
let userNoPick = options.filter(x => x !== this.id);
});
//Hover
el.addEventListener("mouseover",function(){
this.style.marginTop = '10px';
});
//Mouse out
el.addEventListener("mouseout",function(){
if(this.dataset.status !== "selected") {
this.style.marginTop = '50px';
}
});
});
#rock {
background-color: #252422;
font-size: 25px;
text-align: center;
color: #fffcf2;
height: 100px;
width: 200px;
padding: 25px;
margin-left: 50px;
margin-top: 50px;
float: left;
}
#paper {
background-color: #252422;
font-size: 25px;
text-align: center;
color: #fffcf2;
height: 100px;
width: 200px;
padding: 25px;
margin-left: 50px;
margin-top: 50px;
float: left;
}
#scissors {
background-color: #252422;
font-size: 25px;
text-align: center;
color: #fffcf2;
height: 100px;
width: 200px;
padding: 25px;
margin-top: 50px;
margin-right: 50px;
float: right;
}
<main>
<h2>Choose A Play:</h2>
<div id="rock" data-status>
Rock
</div>
<div id="paper" data-status>
Paper
</div>
<div id="scissors" data-status>
Scissors
</div>
</main>
Or the HTML/CSS only approach, then you can leave JavaScript to handle the game logic. Leave the presentation to CSS
label {
background-color: #252422;
font-size: 25px;
text-align: center;
color: #fffcf2;
height: 100px;
width: 200px;
padding: 25px;
margin-left: 50px;
margin-top: 50px;
float: left;
}
label:hover, label:has(:checked) {
margin-top: 10px;
}
label:has(:checked) {
background-color:#ffba08;
}
label > input {
display:none;
}
#rock {
/* background-color: #252422;
font-size: 25px;
text-align: center;
color: #fffcf2;
height: 100px;
width: 200px;
padding: 25px;
margin-left: 50px;
margin-top: 50px;
float: left;*/
}
#paper {
/*background-color: #252422;
font-size: 25px;
text-align: center;
color: #fffcf2;
height: 100px;
width: 200px;
padding: 25px;
margin-left: 50px;
margin-top: 50px;
float: left;*/
}
#scissors {
/* background-color: #252422;
font-size: 25px;
text-align: center;
color: #fffcf2;
height: 100px;
width: 200px;
padding: 25px;
margin-top: 50px;
margin-right: 50px;*/
float: right;
}
<main>
<h2>Choose A Play:</h2>
<label id="rock">
Rock
<input type="radio" name="game" value="rock">
</label>
<label id="paper">
Paper
<input type="radio" name="game" value="paper">
</label>
<label id="scissors">
Scissors
<input type="radio" name="game" value="scissors">
</label>
</main>