I
I
IckiSanZ2018-04-27 23:49:29
JavaScript
IckiSanZ, 2018-04-27 23:49:29

How to implement a keyboard trainer in JavaScript + function help?

Hello, let's describe the situation to understand the big picture. I took a mini-course on JS at the computer academy, but during the time that we were given for it, the teacher managed to explain to us only the basics of the language. I read for myself, of course, but to be honest, I learned not much more (still in the process of learning). And then the day came when you need to do a project for the exam. I got the idea to make a simple keyboard trainer (example: vse10.ru) and not so much like a coder, but beautifully with one function, into which you need to pass the text of the level that the user will subsequently enter, and that's it. Everything should work like this: the letters that the user must enter are displayed on the screen and by pressing the necessary keys (keypress) they will simply change color. I can handle the CSS part myself, but with the event handling, I need help. I already wrote something, but due to the small amount of knowledge and experience, the result ... and what to say, here it is:

let mistakesCounter = 0;

function checkUsersKey (levelText) {
  var theEnd = false;
  var counterLetters = 0;
  var keyName;
  
  function checkKeyEvent(event) {
    //keyName = getChar(event);
    if(theEnd) {
        document.removeEventListener('keypress', checkKeyEvent);
        return;
    }
    while (counterLetters < levelText.length) {
      keyName = getChar(event);
      if(levelText[counterLetters] == keyName){
          alert("Проверка 1 (значение true): работает"); //просто проверка
          counterLetters++;
          //тут будет код, который меняет css буквы
      } else if (keyName == null) {
      	//do nothing
      	alert("Проверка 2")
      } else {
      	alert("Проверка 3 (else): работает");
      	//тут будет код, оповещающий о том, что пользователь допустил ошибку
      	mistakesCounter++;
      }
  }
    theEnd = true;
  }
  while(counterLetters < levelText.length) {
  	document.addEventListener("keypress", checkKeyEvent);
  }
}
checkUsersKey("something");

As you can see, the code is written in such a way that the value is written to keyName only once, and I don’t even have any ideas how to proceed.
I would be grateful if you could help with the function (I need keyName to receive a new value from the user every iteration of the loop, and the loop is executed accordingly.
"Grateful for any help" - Bydlokoder Vladislav

Answer the question

In order to leave comments, you need to log in

2 answer(s)
I
IckiSanZ, 2018-04-28
@IckiSanZ

Already solved the problem. Here is the code:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Typer</title>
    <link rel="stylesheet" type="text/css" href="style.css">
    <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css?family=PT+Sans+Narrow" rel="stylesheet">
  </head>
  <body id="body">
    <div id="main"><b><div id="mistakes"></div></b><div id="alertText"></div><div id="field"><span id="text"></span></div></div>
    <script type="text/javascript" src="script.js"></script>
  </body>
</html>

body {
  margin: 0px;
  background-color: #4BABE7;
}

#main {
  width: 1366px;
  height: 510px;
  background-color: #4BABE7;
}

#field {
  background-color: white;
  margin-left: 150px;
  margin-right: 150px;
  border-radius: 20px;
  transform: translate(0, 110px);
  padding-top: 30px;
  padding-bottom: 30px;
  padding-right: 40px;
  padding-left: 40px;
}
#text {
  font-family: 'Source Sans Pro', sans-serif;
  font-size: 18pt;
}

#mistakes {
  font-family: 'PT Sans Narrow', sans-serif;
  text-decoration: underline;
  color: white;
  font-size: 13pt;
  transform: translate(170px, 105px); 
}

#alertText {
  color: red;
  font-family: 'Source Sans Pro', sans-serif;
  font-size: 19pt;
}

// event.type должен быть keypress
function getChar(event) {
  if (event.which == null) { // IE
    if (event.keyCode < 32) return null; // спец. символ
    return String.fromCharCode(event.keyCode)
  }

  if (event.which != 0 && event.charCode != 0) { // все кроме IE
    if (event.which < 32) return null; // спец. символ
    return String.fromCharCode(event.which); // остальные
  }

  return null; // спец. символ
}

var counterLetters = 0;
var levelText= "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur posuere tellus et leo mollis, vel"; //текст, который будет вводить пользователь
text.innerHTML=levelText;
let mistakesCounter = 0; //Счетчик ошибок
mistakes.innerHTML = ("Кол-во ошибок: " + mistakesCounter);
function checkKeyEvent() {
  	var keyName = getChar(event);
  	if(levelText[counterLetters] == keyName){
          console.log("Введен символ"); //просто проверка
          levelText = levelText.substring(1);
          text.innerHTML = levelText;

      } else if (keyName == null) {
      	//do nothing
      	 console.log("Нажата спец. клавиша");
      	 alertText.innerHTML =("Нажата спец. клавиша");
      	 
      } else {
      	console.log("Введен неверный символ");
      	//тут будет код, оповещающий об ошибке
      	mistakesCounter++;
      	mistakes.innerHTML = ("Кол-во ошибок: " + mistakesCounter);
      }

}
document.addEventListener("keypress", checkKeyEvent);

V
Vladimir Proskurin, 2018-04-28
@Vlad_IT

You're a little confused about how events work (judging by this and the previous question). Roughly speaking, the document.addEventListener("keypress", checkKeyEvent) method creates a key press event that will execute the passed function. If a key is pressed, the keypress event is executed, which will execute the checkKeyEvent function, which is passed the event object (and the pressed key in it).
There is no need to call adding an event in a loop, call it once, and already in the checkKeyEvent function, do the check.

function checkKeyEvent(event) {
     // При нажатии на клавишу выполняется эта функция. Каждый раз.
}
document.addEventListener("keypress", checkKeyEvent);

Your while(counterLetters < levelText.length) { loop will be infinite because the value of levelText or counterLetters does not change. Even if it weren't eternal, it would spawn many event handlers, and we only need one. Cycles are not needed at all. Here's the code. Tried to comment in detail.
let mistakesCounter = 0;
// Это ваша getChar. Не знаю точно, такая же реализация, но это довольно известный код
function getChar(event) {
    if (event.which == null) { // IE
        if (event.keyCode < 32) return null; // спец. символ
        return String.fromCharCode(event.keyCode)
    }

    if (event.which != 0 && event.charCode != 0) { // все кроме IE
        if (event.which < 32) return null; // спец. символ
        return String.fromCharCode(event.which); // остальные
    }

    return null; // спец. символ
}

function checkUsersKey(levelText) {
    var theEnd = false;
    var counterLetters = 0;
    var keyName;

    function checkKeyEvent(event) {
        // Делаем проверку, если текущий символ равен длинне символов...
        if (counterLetters >= levelText.length) {
            // То удаляем обработку события чтобы завершить печатанье.
            document.removeEventListener('keypress', checkKeyEvent);
            // Тут можете вывести сообщение пользователю, что задание закончено
            return;
        }
        keyName = getChar(event);
        // Это ваш код, проверяет, правильно ли пользователь ввел
        if (levelText[counterLetters] == keyName) {
            alert("Проверка 1 (значение true): работает"); //просто проверка
            counterLetters++;
            //тут будет код, который меняет css буквы
        } else if (keyName == null) {
            //do nothing
            alert("Проверка 2")
        } else {
            alert("Проверка 3 (else): работает");
            //тут будет код, оповещающий о том, что пользователь допустил ошибку
            mistakesCounter++;
        }
    }
    // Добавляем обработку события нажатия клавиши на функцию checkKeyEvent
    // Добавляем только один раз, она будет вызывать checkKeyEvent после каждого нажатия и удержания клавиши
    document.addEventListener("keypress", checkKeyEvent);
}
checkUsersKey("something");

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question