【问题标题】:Problem showing questions in a quiz made in javascript在用 javascript 制作的测验中显示问题的问题
【发布时间】:2021-10-10 02:31:05
【问题描述】:

我有一个包含 5 个问题的表单,其中一次向用户显示一个问题,就像在测验中一样,即第一个问题出现在屏幕上,用户回答并转到第二个问题,然后以此类推。

但是,我对问题 3 和 4 有疑问,当我不输入任何内容并按 ENTER 时,屏幕上也会出现问题 2,如下图所示:

[![问题 3 和 4 中的错误][1]][1] [1]:https://i.stack.imgur.com/63pQC.png

我不能同时显示两个问题,一次只显示一个,而且我不知道我哪里错了。

这是表单标签内的代码:

            <form class="questions_box formulario" action="enviar-landing-page-v3.php" method="post">

                <div id="question-1">
                    <h3>The question is: ... ?</h3>
                    <input type="radio" name="objetivo" id="question-1-answer-a" value=1 required oninput="checkObjective()"> Answer 1.<br>
                    <input type="radio" name="objetivo" id="question-1-answer-b" value=2 oninput="checkObjective()"> Answer 2.<br>
                    <input type="radio" name="objetivo" id="question-1-answer-c" value=3 oninput="checkObjective()"> Answer 3.<br>

                    <div class="text-end mt-3">
                        <input type="submit" id="submit1" class="btn btn-primary btn-lg" value="Enviar Resposta" style="display: none;" />
                    </div>

                    <script type="text/javascript">
                        function checkObjective() {
                            if (document.getElementsByName('objetivo').value == '') {
                                document.getElementById('submit1').style.display = 'none';
                            } else {
                                document.getElementById('submit1').style.display = 'block';
                            }
                        }
                    </script>

                </div>

                <div id="question-2">

                    <h3>Quantos anos tem seu filho(a)?</h3>

                    <div class="input-formulario">
                        <i class="far fa-calendar-alt"></i>
                        <input required type="text" name="idade_aluno_lp" id="idade_aluno_lp" placeholder="Digite a idade do aluno" oninput="checkAge()" maxlength="2" />

                    </div>

                    <div class="text-center mt-3">
                        <input type="submit" id="submit2" class="btn btn-primary btn-lg" value="Enviar Resposta" style="display: none;" />
                    </div>

                    <div class="text-end mt-3">
                        <input type="submit" id="previous2" class="btn btn-primary btn-lg" value="Pergunta Anterior" style="display: block;" />
                    </div>

                    <script type="text/javascript">
                        function checkAge() {
                            var countAge = document.getElementById('idade_aluno_lp');
                            countAge.value = countAge.value.replace(/\D/, ''); // Remove caracteres que não sejam números

                            if (countAge.value.length == 0) { // 0 caracteres digitados
                                document.getElementById('submit2').style.display = 'none';
                            } else {
                                document.getElementById('submit2').style.display = 'block';
                            }
                        }
                    </script>

                </div>

                <div id="question-3">
                    <h3>Qual seu nome?</h3>

                    <div class="input-formulario">
                        <i class="far fa-user"></i>
                        <input required type="text" name="nome_lp" id="nome_lp" placeholder="Digite seu nome" oninput="checkName()">
                        <span id="error-name"></span>
                    </div>

                    <div class="text-center mt-3">
                        <input type="submit" id="submit3" class="btn btn-primary btn-lg" value="Enviar Resposta" style="display: none;" />
                    </div>

                    <div class="text-center mt-3">
                        <input type="submit" id="previous3" class="btn btn-primary btn-lg" value="Pergunta Anterior" style="display: block;" />
                    </div>

                    <script type="text/javascript">
                        function checkName() {
                            var countName = document.getElementById('nome_lp');
                            var errorName = document.getElementById('error-name')

                            countName.value = countName.value.replace(/[0-9]/g, ''); // Remove numbers
                            if (countName.value.length < 3) { // 0 chars entered
                                errorName.innerHTML = "O nome precisa ter ao menos 3 caracteres."
                                document.getElementById('submit3').style.display = 'none';
                            } else {
                                errorName.innerHTML = "";
                                document.getElementById('submit3').style.display = 'block';
                            }
                        }
                    </script>

                </div>

                <div id="question-4">
                    <h3>Qual seu email?</h3>

                    <div class="input-formulario">
                        <i class="fas fa-at"></i>
                        <input required type="email" name="email_lp" id="email_lp" placeholder="Digite seu email" oninput="checkEmail()">
                        <span id="error-email"></span>

                    </div>

                    <div class="text-center mt-3">
                        <input type="submit" id="submit4" class="btn btn-primary btn-lg" value="Enviar Resposta" style="display: none;" />
                    </div>

                    <div class="text-end mt-3">
                        <input type="submit" id="previous4" class="btn btn-primary btn-lg" value="Pergunta Anterior" style="display: block;" />
                    </div>

                    <script type="text/javascript">
                        function checkEmail() {
                            var email = document.getElementById('email_lp');
                            var errorEmail = document.getElementById('error-email');

                            if (!email.checkValidity()) {
                                errorEmail.innerHTML = "O email deverá seguir o padrão: meuemail@provedor.com";
                                document.getElementById('submit4').style.display = 'none';
                            } else {
                                errorEmail.innerHTML = "";
                                document.getElementById('submit4').style.display = 'block';
                            }
                        }
                    </script>

                </div>

                <div id="question-5">
                    <h3>Qual seu whatsapp?</h3>

                    <div class="input-formulario">
                        <i class="fab fa-whatsapp"></i>
                        <input required type="text" name="celular_lp" id="celular_lp" placeholder="Digite seu DDD + celular" maxlength="14" onkeypress="return mascaraCelular(event)" oninput="checkMobile()">
                        <span id="error-mobile"></span>
                    </div>

                    <div class="text-end mt-3">
                        <input type="submit" id="submit5" class="btn btn-primary btn-lg" value="Enviar Resposta" style="display: none;" />
                    </div>

                    <div class="text-end mt-3">
                        <input type="submit" id="previous5" class="btn btn-primary btn-lg" value="Pergunta Anterior" style="display: block;" />
                    </div>

                </div>

                <script type="text/javascript">
                    function checkMobile() {
                        var countMobile = document.getElementById('celular_lp');
                        var errorMobile = document.getElementById('error-mobile');

                        if (countMobile.value.length < 13) {
                            errorMobile.innerHTML = "Além do DDD, o número do celular precisa ter ao menos 8 dígitos";
                            document.getElementById('submit5').style.display = 'none';
                        } else {
                            errorMobile.innerHTML = "";
                            document.getElementById('submit5').style.display = 'block';
                        }
                    }
                </script>

            </form>

以及负责显示/隐藏问题的 javascript:

// Variables

var submit1 = document.getElementById('submit1');
var submit2 = document.getElementById('submit2');
var submit3 = document.getElementById('submit3');
var submit4 = document.getElementById('submit4');

var previous2 = document.getElementById('previous2');
var previous3 = document.getElementById('previous3');
var previous4 = document.getElementById('previous4');
var previous5 = document.getElementById('previous5');

// Next question button

submit1.addEventListener('click', function() {
    nextQuestion(2);
    growProgressBar('40%');
})

submit2.addEventListener('click', function() {
    nextQuestion(3);
    growProgressBar('60%');
})

submit3.addEventListener('click', function() {
    nextQuestion(4);
    growProgressBar('80%');
})

submit4.addEventListener('click', function() {
    nextQuestion(5);
    growProgressBar('100%');
})

// grow Progress Bar

function growProgressBar(percentage_width) {
    var bar = document.getElementById('progress_bar');
    bar.style.width = percentage_width;
}

// Shows next question, hides current

function nextQuestion(question_number) {

    var current_question_number = question_number - 1; //question_number is the next question

    var question_number = question_number.toString();
    var current_question_number = current_question_number.toString();

    document.getElementById('question-' + question_number).style.display = 'block';
    document.getElementById('question-' + current_question_number).style.display = 'none';

}

// Previous question button

previous2.addEventListener('click', function() {
    previousQuestion(1);
    shrinkProgressBar('20%');
})

previous3.addEventListener('click', function() {
    previousQuestion(2);
    shrinkProgressBar('40%');
})

previous4.addEventListener('click', function() {
    previousQuestion(3);
    shrinkProgressBar('60%');
})

previous5.addEventListener('click', function() {
    previousQuestion(4);
    shrinkProgressBar('80%');
})

// Shrink Progress Bar

function shrinkProgressBar(percentage_width) {
    var bar = document.getElementById('progress_bar');
    bar.style.width = percentage_width;
}

// Shows previous question, hides current

function previousQuestion(question_number) {

    var current_question_number = question_number + 1;

    var question_number = question_number.toString();
    var current_question_number = current_question_number.toString();

    var el = document.getElementById('question-' + question_number);
    console.log(question_number);
    var el2 = document.getElementById('question-' + current_question_number);

    el.style.display = 'block';
    el2.style.display = 'none';

}

关于 Carsten Massmann 的回答:

代码的问题只是将按钮 type="submit" 更改为 type="button",并且只保留最后一个按钮为 type="submit",但是,我真的很喜欢你的代码,我学到了很多,例如,我从来没有读过最接近的方法。您能否向我解释一下这两行代码是如何工作的(我理解它们是什么):

current = (Q.length + current + inc) % Q.length; // cycle through questions...

上面我不明白你为什么使用问题长度。

在下一行,我不明白我为什么要使用 trim():

(el.value.trim() ? "block" : "none")

我也明白你在问题之间循环,但我需要在循环中划分第一个和最后一个问题,并输入类似 if Q=0,不显示“上一个问题”按钮,如果 Q= 4,最后一个按钮将执行method="POST"和action="next-page"。我相信由于循环,“提交”没有被执行,但我不明白为什么循环优先于提交。

【问题讨论】:

  • 您让自己的生活变得不必要地复杂:尽量避免与ids 合作,因为他们需要单独寻址。这导致在您的情况下重复类似的代码。将 JavaScript 部分放在页面正文中会使其难以阅读和维护。有很多冗余代码和标记。减少这将使您的页面更易于调试和维护。

标签: javascript button display


【解决方案1】:

以下 sn-p 仍然缺少您对各个字段的实际验证功能,但我希望它能够说明如何避免代码和标记中不必要的重复。我正在使用类来处理各种输入元素和“委托事件附件”来组合不同按钮的点击处理。为简单起见,我允许循环回答这些问题。随意改变和适应...

function changeQ(inc){
 current= (Q.length+current+inc)%Q.length; // cycle through questions ... 
 Q.forEach((q,i)=>q.style.display=(i==current?"":"none"))
}
function showHideOK(el){
 let ok=!!el.value.trim();
 el.closest(".input-formulario").querySelector("input.ok").style.display=
   (ok?"block":"none");
 ans[el.name]=ok;
}

document.querySelectorAll("div.input-formulario").forEach((div,i)=>{div.innerHTML+=`<div class="text-end mt-3"><input type="submit" class="btn btn-primary btn-lg back" value="Pergunta Anterior"/></div><div class="text-center mt-3"><input type="submit" class="btn btn-primary btn-lg ok" value="Próxima Pergunta"/></div>`;
  div.addEventListener("input",ev=>{ let el=ev.target;
   if (el.tagName!=="INPUT") return // only act on input elements ...
   showHideOK(el)
   btn.style.display=Object.values(ans).filter(a=>a).length==Q.length?"":"none";
  });
  div.onclick=ev=>{if (ev.target.type=="submit") {
    ev.preventDefault();
    changeQ( ev.target.classList.contains("back")?-1:1 );
  }}
})
const btn = document.querySelector("button"),
      Q=document.querySelectorAll(".question"),
      ans={};

let current=0;
changeQ(0);
btn.style.display="none";
input.ok {display:none} 
<form class="questions_box formulario" action="enviar-landing-page-v3.php" method="post">
  <div class="question">
    <div class="input-formulario">
      <h3>The question is: ... ?</h3>
      <label><input type="radio" name="objetivo" value=1 required> Answer 1.</label><br>
      <label><input type="radio" name="objetivo" value=2> Answer 2.</label><br>
      <label><input type="radio" name="objetivo" value=3> Answer 3.</label><br>
    </div>
  </div>

  <div class="question">
    <h3>Quantos anos tem seu filho(a)?</h3>
    <div class="input-formulario">
      <input required type="number" name="idade_aluno_lp" placeholder="Digite a idade do aluno" maxlength="2" />
    </div>
  </div>

  <div class="question">
    <h3>Qual seu nome?</h3>
    <div class="input-formulario">
      <input required type="text" name="nome_lp" placeholder="Digite seu nome"> <span></span>
    </div>
  </div>

  <div class="question">
    <h3>Qual seu email?</h3>
    <div class="input-formulario">
      <input required type="email" name="email_lp" id="email_lp" placeholder="Digite seu email"> <span></span>
    </div>
  </div>

  <div class="question">
    <h3>Qual seu whatsapp?</h3>
    <div class="input-formulario">
      <input required type="text" name="celular_lp" id="celular_lp" placeholder="Digite seu DDD + celular"
        maxlength="14"> <span></span>
    </div>
  </div>
  <br><button>Enviar todas as respostas</button>

</form>

进一步解释:
我为什么使用Q.length?
表达式current = (Q.length + current + inc)/Q.length 使用Q.length(=问题总数)将current始终保持在现有问题索引的范围内。对于current=0 和inc=-1 和% Q.length 将结果从0 限制为Q.length-1 的情况,Q length+... 一词是必要的。

为什么我使用.trim()?
这只是避免仅包含空格的答案被接受为有效答案的简单方法。

为什么没有“提交”?
我通过在我的事件处理函数中调用 ev.preventDefault() 主动禁用了 submit 操作。

如何提交答案,何时提交?
有许多不同的方法可以做到这一点。我的建议是继续循环回答这些问题,直到所有问题都以有效的方式得到回答。此时会出现一个额外的按钮,一次提交所有答案。我刚刚将该按钮 (btn) 添加到脚本中。它最初通过btn.style.display="none" 隐藏,但在所有问题都得到答案的情况下再次可见:

btn.style.display=Object.values(ans).filter(a=>a).length==Q.length?"":"none";

(全局)对象ans在函数showHideOK()中不断更新:

let ok=!!el.value.trim();
...
ans[el.name]=ok;

【讨论】:

  • 您好,在我的问题文本末尾,我添加了关于您的回答的评论。你能回答我的问题吗?
  • 刚刚更新并完成了我的帖子。也许你可以再检查一下?
猜你喜欢
  • 2014-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多