Javascript - как использовать одно и то же событие onkeydown для вызова разных функций в разных случаях - PullRequest
0 голосов
/ 10 октября 2018

Я пытаюсь сделать простой тест со случайными вопросами.После ввода ответа пользователь может нажать клавишу Enter, чтобы проверить, является ли его ответ правильным или неправильным.В этот момент текстовое поле будет скрыто.

Я бы хотел, чтобы пользователь мог снова нажать клавишу 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() - это то, что я хочу вызвать клавишей Enter.

Ответы [ 4 ]

0 голосов
/ 10 октября 2018

Не вдаваясь в подробности (мне нужно было бы понять гораздо больше о поведении, которое вы хотели бы видеть в различных сценариях. Пример : может ли пользователь вернуться к предыдущему вопросу,изменить ответ и подтвердить?), я бы предложил какой-то индикатор, прикрепленный или связанный (например, с элементом близкого предка), с входом, чтобы отслеживать, был ли ответ еще проверен.

Например, вы можете использовать класс (например, class="answer-validated") или атрибут данных (например, data-validated="true"), если пользователь уже нажал Enter, чтобы проверить значение.В случае класса он будет отсутствовать по умолчанию, и код «проверки» добавит его как часть своей логики.Точно так же атрибут данных может по умолчанию иметь значение «ложь» и может быть обновлен до «истина» при подтверждении ответа.

Преимущество этого подхода состоит в том, что он позволяет напрямую контролировать отслеживание состояния ввода ипотенциально использовать его для других функций, в том числе:

  • сброс состояния ввода, если пользователь хочет ответить,
  • простое восстановление состояния все вопросы, без необходимости обновлять / сбрасывать страницу
  • применение визуальных различий с помощью CSS, основанных на наличии класса или состояния атрибута данных
  • отслеживать количество ответов, которые былипроверил и установил ограничение на максимальное количество проверок (т. е. «Вы можете проверить только 3 ответа перед отправкой своих ответов»)
  • и т. д.

Можно определить состояниеот других элементов на странице, но я бы сказал, что было бы более разумно управлять состоянием ввода на себя, а не определять егоСед о состоянии другого элемента страницы.Это более просто и менее подвержено влиянию изменений других элементов на функциональность ввода.

0 голосов
/ 10 октября 2018

Вы можете проверить внутри функции submit001(), чтобы проверить, скрыт ли элемент управления userInput, и если да, сразу перейти к goToNextQuestion.

0 голосов
/ 10 октября 2018

Есть несколько способов сделать это.Я бы порекомендовал не использовать этот подход, так как нажатие кнопки ввода для отправки не является интуитивно понятным.Я бы порекомендовал добавить кнопку «Отправить».Независимо от того, что вы можете попробовать это:

        
        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>
0 голосов
/ 10 октября 2018

Быстрое решение состоит в том, чтобы добавить дополнительную строку в функцию submit001, прежде чем какой-либо код уже имеет:

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

А в функции gotoNextQuestion вы должны убедиться, чтоочистить текстовое содержимое (удалить «Исправить»).

Но имейте в виду, что событие keydown не срабатывает на элементе input, когда вы его скрываете, поэтому вам следует прослушать это событие в документе.

Еще лучше было бы использовать переменную для этого состояния вместо зависимости от того, что находится в документе HTML.

Вот реализация, которая использует addEventListener вместо того, чтобы иметь код JS внутриваши HTML-теги.Обратите внимание, как он слушает на уровне документа.Также лучше использовать свойство события key, а не keyCode.

Новая переменная execOnEnter определяет, какую функцию выполнять в зависимости от состояния «игры».В коде он изменяется на submit001 или goToNextQuestion:

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>
...