简体   繁体   中英

How do I allow only 1 element to be selected at a time within my click function? ( Vanilla JS )

I am creating a quiz app that pulls data from an API, builds out a series of questions and then loads a different amount of "answer elements" on a quiz page each time, depending on the question selected at random from an array.

Below is the functionality to create a series of clickable "Player Cards" which are effectively answers in the style of CSS cards. The idea is the user selects a card, and then clicks on a check button to run the functionality to check if correct or not.

The functionality works fine apart from one thing. The user can select all cards.

The problem I have is you can click all answers and they all get the CSS classes and the data gets passed for all cards/answers selected.

I only want to allow the user to select one answer. They can click on any card, and change their mind but their should only ever be one answer they can select and in turn process the answer check function on.

I can't figure out how to do this? Could anyone help me to understand how I need to change this code for that to happen?

function addClickEvent(answers) {
  const playerCard = document.querySelectorAll(".player-card");
  for (i = 0; i < playerCard.length; i++) {
    playerCard[i].setAttribute("id", [i]);
    playerCard[i].addEventListener("click", (e) => {
      clickedPlayer = e.target;
      clickedPlayer.classList.add("border-lime-500");
      clickedPlayer.classList.add("border-8");
      let userAnswer = answers[clickedPlayer.id];
      
      checkButton.addEventListener("click", () => {
        checkAnswer(userAnswer, answers);
      });
    });
  }
}

Store the answer in a variable of a greater scope than the listener. Whenever any answer will be submitted the variable will be overwritten with it. Afterwards declare a singular checkButton listener. If the variable holds an answer that isn't null, check the answer.

function addClickEvent(answers) {
  const playerCard = document.querySelectorAll(".player-card");
  let userAnswer = null;
  
  for (i = 0; i < playerCard.length; i++) {
    playerCard[i].setAttribute("id", [i]);
    playerCard[i].addEventListener("click", (e) => {
      clickedPlayer = e.target;
      clickedPlayer.classList.add("border-lime-500");
      clickedPlayer.classList.add("border-8");
      userAnswer = answers[clickedPlayer.id];
    });
  }
  
  checkButton.addEventListener("click", () => {
        if(!userAnswer) return alert("Select an answer first!");
        checkAnswer(userAnswer, answers);
   });
}

The code above doesn't make frontend to "diselect" the cards when the others are clicked if that's what you want too, but it is an easy fix.

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