skip to Main Content

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.

2

Answers


  1. I’m not sure why removeEventListener isn’t working. I tried a few different options and one I managed to get work was to replace

     document.getElementById(userSelection).removeEventListener('mouseout', out)
    

    with

    document.getElementById(userSelection).onmouseout = undefined;
    

    A little hacky, but it works.

    Hope that helps!

    Login or Signup to reply.
  2. 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>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search