Как использовать функцию в функции?
Решил создать программку-тест в которой проверяется результат умножения для двух случайных чисел. Пользователь в поле ввода записывает результат, а программа через 10 вопросов должна вернуть статистику. Вот мой код:
function main() {
var numb1 = Math.round(Math.random() * 9); // Вот эти строчки кода занести в функцию
var numb2 = Math.round(Math.random() * 9);
var result = numb1 * numb2;
var rate = 0;
var counter = 0;
var input = document.getElementById("text");
var str = document.createElement('span');
str.innerHTML = numb1 + " x " + numb2 + " ="; //И эти
input.before(str);
var button = document.createElement('button');
button.innerHTML = "Calculate";
document.body.append(button);
button.onclick = function() {
if (mainForm.text.value == result) {
rate++;
counter++;
} else {
counter++;
}
if (counter == 10) {
var str1 = document.getElementById("firstSpan");
str1.style.display = "block";
str1.innerHTML = "Rate:" + rate * 10 + "%";
} else {
document.getElementById("firstSpan").style.display = "none";
}
if (counter == 10) {
var str2 = document.getElementById("secondSpan");
str2.style.display = "block";
str2.innerHTML = " " + rate + " correct answers from 10";
rate = 0;
counter = 0;
} else {
document.getElementById("secondSpan").style.display = "none"
}
}
}
<body onload="main()">
<span id="firstSpan"></span>
<span id="secondSpan"></span>
<form id="mainForm">
<input type="text" id="text">
</form>
</body>
Программа работает корректно, но осталось только понять, как постоянно менять числа, т.к сейчас остаются одни и те же. Я понимаю, почему это так работает и придумал решение, но не знаю, как это сделать технически.
Суть моего решения: те строчки кода, где генерируется случайные числа и те строчки кода, где эти числа выводятся в документ, вот фото:
нужно вынести в отдельную функцию и вызывать её нажатием кнопки, но я не знаю как.
Ответы (3 шт):
После некоторого времени разбирательств и чтения документация я понял, что разобраться с функцией я не могу, поэтому придумал другой способ. Я удалял строку с помощью метода remove:
var clearStr = document.getElementById('str');
clearStr.remove(str);
var clearButton = document.getElementById('button');
clearButton.remove(button);
main();
mainForm.text.value = "";
Хоть и не разобрался с функциями, но сделал сам, может быть кому-то когда-то это пригодится!
Вот как можно вынести в отдельную функцию.
function main() {
var numb1 = 0
var numb2 = 0
var result = 0;
var rate = 0;
var counter = 0;
var input = document.getElementById("text");
var str = document.createElement('span');
input.before(str);
var button = document.createElement('button');
button.innerHTML = "Calculate";
document.body.append(button);
function generateExample() {
numb1 = Math.round(Math.random() * 9); // Вот эти строчки кода занести в функцию
numb2 = Math.round(Math.random() * 9);
result = numb1 * numb2;
str.innerHTML = numb1 + " x " + numb2 + " ="; //И эти
input.value = '';
}
generateExample();
button.onclick = function() {
if (mainForm.text.value == result) {
rate++;
counter++;
} else {
counter++;
}
if (counter == 10) {
var str1 = document.getElementById("firstSpan");
str1.style.display = "block";
str1.innerHTML = "Rate:" + rate * 10 + "%";
} else {
document.getElementById("firstSpan").style.display = "none";
}
if (counter == 10) {
var str2 = document.getElementById("secondSpan");
str2.style.display = "block";
str2.innerHTML = " " + rate + " correct answers from 10";
rate = 0;
counter = 0;
} else {
document.getElementById("secondSpan").style.display = "none"
}
generateExample();
}
}
<body onload="main()">
<span id="firstSpan"></span>
<span id="secondSpan"></span>
<form id="mainForm">
<input type="text" id="text">
</form>
</body>
document.addEventListener("DOMContentLoaded", main);
function main() {
let answers = {
correct: 0,
total: 0,
};
let answer = id("answer");
let message = id("message");
let example = create_example();
id("btn").addEventListener("click", submit);
// Передается "имя" функции, которую нужно вызвать при клике
answer.addEventListener("keyup", function(e) {
if (e.key == "Enter") submit(); // вызывается "вручную", через скобки()
// Лень кликать на кнопку, пусть срабатывает и при нажатии Enter
});
/***/
function submit() {
if (answer.value == example.result) answers.correct++; // (*1)
(++answers.total == 10) ? (show_message(), reset_answers()) : hide_message(); // (*2)
example = create_example();
answer.value = "";
}
/*** Вызываются из submit() */
function show_message() {
let rate = answers.correct / answers.total;
message.innerHTML = `
Rate: ${ rate * 100 }% <br>
${ answers.correct } correct answers from 10
`;
message.style.display = "block";
}
function hide_message() {
message.style.display = "none";
}
function reset_answers() {
answers.correct = answers.total = 0;
}
function create_example() {
let a = Math.random() * 10 | 0;
let b = Math.random() * 10 | 0;
id("math-example").textContent = `${a} * ${b} =`;
answer.focus(); // Пусть фокус сразу стоит на поле при каждой новой задаче
return {
result: a * b,
};
}
/***/
function id(str) { // мелкая обертка, лень везде писать document.getElementById
return document.getElementById(str);
}
}
<span id="math-example"></span>
<input id="answer">
<hr>
<button id="btn">Submit</button>
<p id="message"></p>
(*1) if (answer.value == example.result) answers.correct++;
Нужно понимать, что answer.value — строка, example.result - число. При нестрогом сравнении, строка неявно приводится к числовому типу. А если например ничего не введут, а правильный result — 0, сравнение "" == 0 выдаст true. При необходимости надо бы добавить валидацию ответа)
(*2) (++answers.total == 10) ? (show_message(), reset_answers()) : hide_message();
Менее выпендрежный аналог:
answers.total++;
if (answers.total == 10) {
show_message();
reset_answers();
} else {
hide_message();
}
P.s. var numb1 = Math.round(Math.random() * 9); — Это проблема, и вот почему:
let arr = new Array(10).fill(0);
for (let i = 0; i < 1000000; i++) {
let index = Math.round(Math.random() * 9);
arr[index]++;
}
console.log( Object.entries(arr).join("\n") );
.as-console-wrapper { min-height: 100vh; }
Выпадают числа в интервале [0, 9), числа от 0 до 0.5 округляются до нуля, числа от 8.5 до 9 → до девяти. В итоге 0 и 9 выпадают вдвое реже, чем остальные. Поэтому эти строчки заменил на Math.floor(Math.random() * 10);
