Я новичок в программировании и пытаюсь сделать калькулятор с помощью html и js. Я хочу, чтобы калькулятор выглядел как реальный калькулятор, поэтому, когда я нажимаю кнопку с цифрой, число отображается в блоке. Я сделал эту функцию, но я не могу очистить число, отображаемое на блоке, нажав кнопку «AC». Что я должен изменить, чтобы функция очистки работала.
часть html-кода
<tr><td colspan = "5" id = "result" height = "40"></td></tr>
<tr>
<td id = "seven" class = "number" onclick = "output()">7</td>
<td id = "eight" class = "number" onclick = "output()">8</td>
<td id = "nine" class = "number" onclick = "output()">9</td>
<td id = "C" >C</td>
<td id = "AC" onclick = "clear()">AC</td>
</tr>
js-код
let result = document.getElementById("result");
function output() {
result.innerHTML = result.innerHTML + event.target.innerHTML;
};
function clear() {
result.innerHTML = "";
};
Я попробовал функцию очистки, чтобы очистить innerhtml, но это не сработало. Должен ли я изменить код или есть проблема с функцией вывода. Как использовать функцию очистки для очистки отображаемого вывода.
Фрагмент стека
let result = document.getElementById("result");
function output() {
result.innerHTML = result.innerHTML + event.target.innerHTML;
};
function clear() {
result.innerHTML = "";
};
<table>
<tr><td colspan = "5" id = "result" height = "40"></td></tr>
<tr>
<td id = "seven" class = "number" onclick = "output()">7</td>
<td id = "eight" class = "number" onclick = "output()">8</td>
<td id = "nine" class = "number" onclick = "output()">9</td>
<td id = "C" >C</td>
<td id = "AC" onclick = "clear()">AC</td>
</tr>
</table>
Это одна из нескольких причин, по которым нет использует обработчики событий в стиле onxyz
-атрибутов. Они могут вызывать только глобальные функции, а глобальное пространство имен очень переполнено и подвержено конфликтам имен. Они также работают в сложной области, которая включает не только глобальную среду, но также все свойства и методы элемента, на котором находится атрибут onxyz
, и всех его родительских элементов. Вот что происходит с вами: вы сталкиваетесь с ситуацией, когда clear
существует в этой специальной области, потому что она существует в элементе или его родителях. (В частности, он включен HTMLDocument
; смотрите ответ внизу.)
Вместо этого используйте addEventListener
. Он позволяет вам использовать неглобальные значения и надежно прикрепляет точную функцию, которую вы ему даете. Например, чтобы сделать это с минимальными изменениями того, что у вас есть:
let result = document.getElementById("result");
for (const id of ["seven", "eight", "nine"]) {
document.getElementById(id).addEventListener("click", output);
}
document.getElementById("AC").addEventListener("click", clear);
function output() {
result.innerHTML = result.innerHTML + event.target.innerHTML;
} // <== Side note: No `;` here, this is a function *declration*
function clear() {
result.innerHTML = "";
} // <== Same
Живой пример:
let result = document.getElementById("result");
for (const id of ["seven", "eight", "nine"]) {
document.getElementById(id).addEventListener("click", output);
}
document.getElementById("AC").addEventListener("click", clear);
function output() {
result.innerHTML = result.innerHTML + event.target.innerHTML;
}
function clear() {
result.innerHTML = "";
}
<table>
<tr><td colspan = "5" id = "result" height = "40"></td></tr>
<tr>
<td id = "seven" class = "number">7</td>
<td id = "eight" class = "number">8</td>
<td id = "nine" class = "number">9</td>
<td id = "C" >C</td>
<td id = "AC">AC</td>
</tr>
</table>
(В современном кодировании у вас, вероятно, было бы это в модуль, а не в скрипте, чтобы он не был в глобальной области.)
Но, в идеале нам не нужно было бы давать каждому элементу такой id
и ссылаться на них конкретно. Мы могли бы, например, использовать класс number
, который у вас есть для цифр:
for (const element of document.querySelectorAll(".number")) {
element.addEventListener("click", output);
}
document.getElementById("AC").addEventListener("click", clear);
Живой пример:
let result = document.getElementById("result");
for (const element of document.querySelectorAll(".number")) {
element.addEventListener("click", output);
}
document.getElementById("AC").addEventListener("click", clear);
function output() {
result.innerHTML = result.innerHTML + event.target.innerHTML;
}
function clear() {
result.innerHTML = "";
}
<table>
<tr><td colspan = "5" id = "result" height = "40"></td></tr>
<tr>
<td class = "number">7</td>
<td class = "number">8</td>
<td class = "number">9</td>
<td id = "C" >C</td>
<td id = "AC">AC</td>
</tr>
</table>
Так откуда взялся clear
? Это включено HTMLDocument
. Ваш код работает в содержимом, которое выглядит так (могут быть и другие слои):
with (document) {
with (/* the `html` element*/) {
with (/* the `body` element*/) {
with (/* the `table` element for your table*/) {
with (/* the [implied] `tbody` element for your table*/) {
with (/* the `tr` element for your table row*/) {
with (/* the `td` element for your AC cell*/) {
clear(); // <== Your code
}
}
}
}
}
}
}
Таким образом, clear
находится в HTMLDocument
, используя это вместо clear
, которое вы объявили в глобальной области видимости.
Отсутствие ясности относительно того, где используется clear
, также является основной причиной, по которой with
заявление фактически устарел. (Например, это запрещено в строгом режиме, и весь новый код должен быть написан с использованием строгого режима.) :-)
Просто измените ясное имя функции, которое будет работать
let result = document.getElementById("result");
function output() {
result.innerHTML = result.innerHTML + event.target.innerHTML;
}
function clearResult() {
document.getElementById("result").innerHTML = "";
}
Проблема заключается в том, что функция "clear()" уже используется другой вещью, поэтому вы не можете ее использовать, самый быстрый способ решить вашу проблему - изменить только имя функции. Вы можете проверить мой 1-й пример для этого.
Другой способ избежать этого - просто обернуть функцию внутри другой вещи, как вы сказали, что все еще учитесь, поэтому может также показать вам возможность. Вы можете проверить это на моем втором примере.
let result = document.getElementById("result");
function calcOutput() {
result.innerHTML = result.innerHTML + event.target.innerHTML;
};
function calcClear() {
result.innerHTML = "";
};
// For Second Example
const calculator = {
output : () => {
result.innerHTML = result.innerHTML + event.target.innerHTML;
},
clear : () => {
result.innerHTML = "";
}
};
<!-- First Example -->
<table>
<tbody>
<tr><td colspan = "5" id = "result" height = "40"></td></tr>
<tr>
<td id = "seven" class = "number" onclick = "calcOutput()">7</td>
<td id = "eight" class = "number" onclick = "calcOutput()">8</td>
<td id = "nine" class = "number" onclick = "calcOutput()">9</td>
<td id = "C" >C</td>
<td id = "AC" onclick = "calcClear()">AC</td>
</tr>
</tbody>
</table>
<!-- Second Example -->
<table>
<tbody>
<tr><td colspan = "5" id = "result2nd" height = "40"></td></tr>
<tr>
<td id = "seven2nd" class = "number" onclick = "calculator.output()">7</td>
<td id = "eight2nd" class = "number" onclick = "calculator.output()">8</td>
<td id = "nine2nd" class = "number" onclick = "calculator.output()">9</td>
<td id = "C2nd" >C</td>
<td id = "AC2nd" onclick = "calculator.clear()">AC</td>
</tr>
</tbody>
</table>
Поскольку вы используете встроенный обработчик событий, ваша глобальная функция window.clear
затенена устаревшей document.clear
.
В обработчике событий в качестве HTML-атрибута объект Document находится в цепочке областей перед объектом Window.
Вы можете проверить это, запустив console.info(clear === document.clear);
в своем фрагменте.
Вы должны попытаться создать область своего приложения с помощью IIFE, а затем использовать Event Listener для правильного обратного вызова для каждого события.
Вы должны использовать более конкретные теги HTML, такие как
input
,button
и т. д. И вам не следует сильно полагаться на таблицы для целей макета, вместо этого вы можете изучить CSS для стилизации макета вашей веб-страницы.