Javascript - 如何使用同一个onkeydown事件在不同的场合调用不同的函数

Javascript - how to use the same onkeydown event to call different functions on different occasions

我正在尝试用随机问题做一个简单的测验。 输入答案后,用户可以按回车键检查自己的答案是否正确。在那一刻,文本框将被隐藏。

我希望用户能够再次按 Enter 键继续下一个问题。但是我该怎么做,因为我已经有一个函数正在使用该键调用?

这就是我正在使用的:

    var country = ["Italy", "Spain", "Portugal", "France"];
    var capital = ["rome", "madrid", "lisbon", "paris"];
    var random001 = Math.floor(Math.random() * country.length);

    document.getElementById("country").innerHTML = country[random001];

    function submit001() {
        var b = input001.value.toLowerCase();
        var text;
        switch (true) {
            case random001 == 0 && b == capital[0]:
            case random001 == 1 && b == capital[1]:
            case random001 == 2 && b == capital[2]:
            case random001 == 3 && b == capital[3]:
                text = "Correct!";
                hideAndShowDIV();
                break;
            default:
                text = input001.value.bold() + " is not correct!";
                document.getElementById("input001").value = "";
        }
        document.getElementById("answer001").innerHTML = text;
    }

    function hideAndShowDIV() {
        var x = document.getElementById("userInput");
        if (x.style.display === "none") {
            x.style.display = "block";
        } else {
            x.style.display = "none";
        }
    }

    function goToNextQuestion() {
        random001 = Math.floor(Math.random() * country.length);
        document.getElementById("country").innerHTML = country[random001];
        hideAndShowDIV()
        document.getElementById("input001").focus();
    }
    <p id="message001">What is the capital of <text id="country"></text>?</p>
    <div id="userInput" style="display:block">
        <input type="text" id="input001" autofocus onKeyDown="if(event.keyCode==13) submit001();">
    </div>
    <p id="answer001"></p>

function goToNextQuestion()就是我要用回车键调用的

一个快速的解决方案是在函数 submit001 中的任何已有代码之前添加额外的一行:

if (document.getElementById("answer001").textContent === "Correct") {
    goToNextQuestion();
}

然后在函数 gotoNextQuestion 中,您应该确保清除该文本内容(删除 "Correct")。

但请注意,隐藏 input 元素时不会触发 keydown 事件,因此您应该在文档中收听该事件。

更好的方法是为该状态使用一个变量,而不是依赖于 HTML 文档中的内容。

这是一个使用 addEventListener 而不是在 HTML 标签中包含 JS 代码的实现。请注意它如何在文档级别进行侦听。另外最好使用事件 key 属性 而不是 keyCode

一个新变量execOnEnter 定义了根据"game" 的状态执行哪个函数。它在代码中更改为 submit001goToNextQuestion:

var country = ["Italy", "Spain", "Portugal", "France"];
var capital = ["rome", "madrid", "lisbon", "paris"];
var random001 = Math.floor(Math.random() * country.length);

document.getElementById("country").textContent = country[random001];

var execOnEnter = submit001;
document.addEventListener("keydown", function (e) {
    if (e.key !== "Enter") return;
    execOnEnter();
});

function submit001() {
    var b = input001.value.toLowerCase();
    var text;
    if (b === capital[random001]) {
        text = "Correct!";
        hideAndShowDIV();
        execOnEnter = goToNextQuestion;
    } else {
        text = input001.value.bold() + " is not correct!";
    }
    document.getElementById("input001").value = "";
    document.getElementById("answer001").innerHTML = text;
}

function hideAndShowDIV() {
    var x = document.getElementById("userInput");
    if (x.style.display === "none") {
        x.style.display = "block";
    } else {
        x.style.display = "none";
    }
}

function goToNextQuestion() {
    document.getElementById("answer001").innerHTML = "";
    random001 = Math.floor(Math.random() * country.length);
    document.getElementById("country").innerHTML = country[random001];
    hideAndShowDIV()
    execOnEnter = submit001;
    document.getElementById("input001").focus();
}
<p id="message001">What is the capital of <text id="country"></text>?</p>
<div id="userInput" style="display:block">
    <input type="text" id="input001" autofocus>
</div>
<p id="answer001"></p>

您可以在 submit001() 函数内部检查 userInput 控件是否被隐藏,如果是,直接转到 goToNextQuestion.

有几种方法可以做到这一点。不过我建议不要使用这种方法,因为点击回车按钮提交是不直观的。我建议添加一个 'submit' 按钮。无论如何你可以试试这个:

        
        var country = ["Italy", "Spain", "Portugal", "France"];
        var capital = ["rome", "madrid", "lisbon", "paris"];
        var random001 = Math.floor(Math.random() * country.length);

        document.getElementById("country").innerHTML = country[random001];

        function input001_onKeyDown(e){
          if(e.keyCode === 13){
            submit001();
          } else {
            clearParagraph();
          }
        }

        function submit001() {

            var b = input001.value.toLowerCase();
            document.querySelector("#input001").value = ''
            var text;
            switch (true) {
                case random001 == 0 && b == capital[0]:
                case random001 == 1 && b == capital[1]:
                case random001 == 2 && b == capital[2]:
                case random001 == 3 && b == capital[3]:
                    text = "Correct! " + b + " is the capital of " + country[random001];
                    goToNextQuestion();
                    break;
                default:
                    text = b + " is not correct!";
                    document.getElementById("input001").value = "";
            }
            document.getElementById("answer001").innerHTML = text
        }

        function hideAndShowDIV() {
            var x = document.getElementById("userInput");
            if (x.style.display === "none") {
                x.style.display = "block";
            } else {
                x.style.display = "none";
            }
        }

        function goToNextQuestion() {
            random001 = Math.floor(Math.random() * country.length);
            document.getElementById("country").innerHTML = country[random001];
            document.getElementById("input001").focus();
        }

        function clearParagraph(){
          document.querySelector("#answer001").innerHTML = ''
        }
    <p id="message001">What is the capital of <text id="country"></text>?</p>
    <div id="userInput" style="display:block">
        <input type="text" id="input001" autofocus onKeyDown="input001_onKeyDown(event)">
    </div>
    <p id="answer001"></p>

无需赘述太多细节(我必须更多地了解您在各种情况下想要的行为......示例:用户可以去回到上一个问题,更改答案,然后重新验证?),我建议在输入上附加或关联某种指示符(即,在一个接近的祖先元素上)以跟踪答案是否已经过验证.

例如,如果用户已经点击 Enter,您可以使用 class(例如 class="answer-validated")或数据属性(例如 data-validated="true")检查值。在 class 的情况下,默认情况下它将不存在,并且 "validation" 代码会将其添加为其逻辑的一部分。同样,数据属性可以默认为 "false" 并在验证答案时更新为 "true"。

这种方法的好处是它允许您直接控制输入状态的跟踪,并可能将其重新用于其他功能,包括:

  • 重置输入状态,如果用户想重新回答,
  • 轻松重置所有问题的状态,而无需refresh/reset页面
  • 根据 class 的存在或数据属性的状态
  • ,应用与 CSS 的视觉差异
  • 跟踪已检查的答案数量并限制最大验证数量(即 "You can only check 3 answers before submitting your answers")
  • 等等

可以从页面上的其他元素推断出状态,但我认为管理输入本身的状态比根据另一个页面元素的状态来确定它更有意义.它更直接,更不容易对其他元素的更改影响输入的功能。