单选按钮值不清晰和警报消息问题

Radio button values not getting clear and alert messages issue

我正在构建测验应用程序。我面临 checkAns() 函数的问题。我面临的问题是在给出 correct/incorrect 后,我的应用程序卡在警告消息“至少选择一个选项”,即使我已经选择了一个选项。我必须多次单击警报消息“选择至少一个选项”的确定按钮才能出现下一个问题。我试过调试它,但我找不到问题。

const quizData = [{ question: 'How old are you?', a: '10', b: '20', c: '23', d: '50', correctAns: 'c', count: 0 }, { question: 'WWW stands for?', a: 'World Wide Web', b: 'Web Wide World', c: 'Worldy Wide web', d: 'none of the above', correctAns: 'a', count: 0 }, { question: 'Adult age in india?', a: '20', b: '18', c: '17', d: '50', correctAns: 'b', count: 0 }, { question: 'Capital of India?', a: 'Bhopal', b: 'Mumbai', c: 'Kolkata', d: 'New Delhi', correctAns: 'd', count: 0 }, { question: 'Capital of MP?', a: 'Bhopal', b: 'Burhanpur', c: 'Indore', d: 'Guna', correctAns: 'a', count: 0 } ];

const question = document.getElementById('question')
const optionA = document.getElementById('a_text')
const optionB = document.getElementById('b_text')
const optionC = document.getElementById('c_text')
const optionD = document.getElementById('d_text')
const input = document.querySelectorAll('input')
const btnSubmit = document.getElementById('submit')
const radioBtnValue = document.getElementsByName('answer')
let index;
function getRandomQuestion() {
  return (Math.floor(Math.random() * quizData.length))
}
function radioBtn() {
  let element;
  radioBtnValue.forEach((el) => {
    if (el.checked) {
      element = el.id
      return;
    }
    return;
  })
  return element
}
function clearRadioBtnValues() {
  radioBtnValue.forEach((el) => {
    el.checked = false
  })
  return
}
function checkAns(value, index) {
  if (value === quizData[index].correctAns) {
    alert('correct ans')
    clearRadioBtnValues()
    startQuiz()
  } else if (value === undefined) {
    alert('choose atleast one option')
  } else {
    alert('incorrect ans')
    clearRadioBtnValues()
    startQuiz()
  }
}
function startQuiz() {
  index = getRandomQuestion()
  if (quizData[index].count === 0) {
    question.innerHTML = quizData[index].question
    optionA.innerHTML = quizData[index].a
    optionB.innerHTML = quizData[index].b
    optionC.innerHTML = quizData[index].c
    optionD.innerHTML = quizData[index].d
    quizData[index].count++
      btnSubmit.addEventListener('click', function() {
        let radioBtnValue = radioBtn()
        checkAns(radioBtnValue, index)
      })
  }
}
window.onload = startQuiz
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@200;400;600&display=swap");
* {
  box-sizing: border-box;
}

body {
  background-color: #b8c6db;
  background-image: linear-gradient(315deg, #b8c6db 0%, #f5f7fa 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Poppins", sans-serif;
  margin: 0;
  min-height: 100vh;
}

.quiz-container {
  background-color: #fff;
  border-radius: 10px;
  box-shadow: 0 0 10px 2px rgba(100, 100, 100, 0.1);
  overflow: hidden;
  width: 600px;
  max-width: 100%;
}

.quiz-header {
  padding: 4rem;
}

h2 {
  padding: 1rem;
  text-align: center;
  margin: 0;
}

ul {
  list-style-type: none;
  padding: 0;
}

ul li {
  font-size: 1.2rem;
  margin: 1rem 0;
}

ul li label {
  cursor: pointer;
}

button {
  background-color: #8e44ad;
  border: none;
  color: white;
  cursor: pointer;
  display: block;
  font-family: inherit;
  font-size: 1.1rem;
  width: 100%;
  padding: 1.3rem;
}

button:hover {
  background-color: #732d91;
}

button:focus {
  background-color: #5e3370;
  outline: none;
}
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Quiz App</title>
  <link rel="stylesheet" href="style.css">
  <script src="./script.js" defer></script>
</head>

<body>
  <div class="quiz-container" id="quiz">
    <div class="quiz-header">
      <h2 id="question">Question text</h2>
      <ul id="main-ul">
        <li>
          <input type="radio" id="a" name="answer" class="answer" />
          <label id="a_text" for="a"></label>
        </li>
        <li>
          <input type="radio" id="b" name="answer" class="answer" />
          <label id="b_text" for="b"></label>
        </li>
        <li>
          <input type="radio" id="c" name="answer" class="answer" />
          <label id="c_text" for="c"></label>
        </li>
        <li>
          <input type="radio" id="d" name="answer" class="answer" />
          <label id="d_text" for="d"></label>
        </li>
      </ul>
    </div>
    <button id="submit">Submit</button>
  </div>

</body>

</html>

每次调用 startQuiz 时,您都将事件监听器添加到按钮

所以 let radioBtnValue = radioBtn(); checkAns(radioBtnValue, index) 会在第一次开始测验后被一次又一次地调用

这是一个更简单的版本。我保留了你的 HTML 但重命名了按钮,因为你不应该使用“提交”作为 ID 或名称,以防你在要使用脚本提交的表单中。

const quizData = [{ question: 'How old are you?', a: '10', b: '20', c: '23', d: '50', correctAns: 'c', count: 0 }, { question: 'WWW stands for?', a: 'World Wide Web', b: 'Web Wide World', c: 'Worldy Wide web', d: 'none of the above', correctAns: 'a', count: 0 }, { question: 'Adult age in india?', a: '20', b: '18', c: '17', d: '50', correctAns: 'b', count: 0 }, { question: 'Capital of India?', a: 'Bhopal', b: 'Mumbai', c: 'Kolkata', d: 'New Delhi', correctAns: 'd', count: 0 }, { question: 'Capital of MP?', a: 'Bhopal', b: 'Burhanpur', c: 'Indore', d: 'Guna', correctAns: 'a', count: 0 } ] 

function getRandomQuestion() {
  return (Math.floor(Math.random() * quizData.length))
}

function checkAns(index) {
  const rad = document.querySelector("#main-ul [type=radio]:checked"); // only find checked radio
  const value = rad ? rad.id : ""; // if none checked, set empty value

  if (!value) {
    alert('choose at least one option')
    return; // leave the function
  }
  const res = value === quizData[index].correctAns ? 'correct ans' : 'incorrect ans'; // this is called a ternary
  alert(res);
  [...document.querySelectorAll("#main-ul [type=radio]")].forEach(el => el.checked = false);
  
  quizData.splice(index, 1); // remove question
  
  startQuiz();
}

let index; // global var.
function startQuiz() {
  if (quizData.length===0) {
    document.getElementById('question').innerHTML = "No more questions";
    document.getElementById("main-ul").style.display="none";
    document.getElementById("subbut").style.display="none";
    return;
  }
  index = getRandomQuestion();
  document.getElementById('question').innerHTML = quizData[index].question;
  // DRY, don't repeat yourself
  ["a","b","c","d"].forEach(letter => document.getElementById(letter+'_text').innerHTML = quizData[index][letter])
}
window.addEventListener("load", function() { // when the page loads
  document.getElementById('subbut').addEventListener('click', function() {
    checkAns(index);
  })
  startQuiz();
})
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@200;400;600&display=swap");
* {
  box-sizing: border-box;
}

body {
  background-color: #b8c6db;
  background-image: linear-gradient(315deg, #b8c6db 0%, #f5f7fa 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Poppins", sans-serif;
  margin: 0;
  min-height: 100vh;
}

.quiz-container {
  background-color: #fff;
  border-radius: 10px;
  box-shadow: 0 0 10px 2px rgba(100, 100, 100, 0.1);
  overflow: hidden;
  width: 600px;
  max-width: 100%;
}

.quiz-header {
  padding: 4rem;
}

h2 {
  padding: 1rem;
  text-align: center;
  margin: 0;
}

ul {
  list-style-type: none;
  padding: 0;
}

ul li {
  font-size: 1.2rem;
  margin: 1rem 0;
}

ul li label {
  cursor: pointer;
}

button {
  background-color: #8e44ad;
  border: none;
  color: white;
  cursor: pointer;
  display: block;
  font-family: inherit;
  font-size: 1.1rem;
  width: 100%;
  padding: 1.3rem;
}

button:hover {
  background-color: #732d91;
}

button:focus {
  background-color: #5e3370;
  outline: none;
}
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Quiz App</title>
  <link rel="stylesheet" href="style.css">
  <script src="./script.js" defer></script>
</head>

<body>
  <div class="quiz-container" id="quiz">
    <div class="quiz-header">
      <h2 id="question">Question text</h2>
      <ul id="main-ul">
        <li>
          <input type="radio" id="a" name="answer" class="answer" />
          <label id="a_text" for="a"></label>
        </li>
        <li>
          <input type="radio" id="b" name="answer" class="answer" />
          <label id="b_text" for="b"></label>
        </li>
        <li>
          <input type="radio" id="c" name="answer" class="answer" />
          <label id="c_text" for="c"></label>
        </li>
        <li>
          <input type="radio" id="d" name="answer" class="answer" />
          <label id="d_text" for="d"></label>
        </li>
      </ul>
    </div>
    <button id="subbut">Submit</button>
  </div>

</body>

</html>

如果您提交答案并重新分配新的答案,您的检查答案功能将再次分配点击事件。

使用 element.addEventListener() 您可以根据需要向单个节点添加任意数量的事件。使用 element.onclick = function(){} 或 element.setAttribute("onclick", "string...");您可以只分配一个并每次都覆盖它。

如果将分配函数方法与检查结果和分配新问题分开,就可以解决这个问题。