Home > Software design >  Cant clear the innerHTML
Cant clear the innerHTML

Time:04-02

I am new to programming and I am trying to make a calculator by using html and js. I want the calculator to look like a real-life calculator so when I click the number button, the number will show in the block. I have made this function, but I can't clear the number shown on block by clicking "AC" button. What should I change to make the clear function work.

part of html code

<tr><td colspan="5" id="result" height="40"></td></tr>

<tr>
    <td id="seven"  onclick = "output()">7</td>
    <td id="eight"  onclick = "output()">8</td>
    <td id="nine"  onclick = "output()">9</td>
    <td id="C" >C</td>
    <td id="AC" onclick = "clear()">AC</td>
</tr>

js code

let result = document.getElementById("result");

function output() {
    result.innerHTML =  result.innerHTML   event.target.innerHTML;
 };  

function clear() {
    result.innerHTML = "";
 };

I tried the clear function to clear the innerhtml but it didn't work. Should I change the code or there is a problem of the output function. How to use the clear fucntion to clear the output displayed.

Stack Snippet

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"  onclick = "output()">7</td>
    <td id="eight"  onclick = "output()">8</td>
    <td id="nine"  onclick = "output()">9</td>
    <td id="C" >C</td>
    <td id="AC" onclick = "clear()">AC</td>
</tr>
</table>

CodePudding user response:

This is one of the several reasons not to use onxyz-attribute-style event handlers. They can only call global functions, and the global namespace is very crowded and prone to naming conflicts. They also run in a complicated scope that incorporates not only the global environment, but also all of the properties and methods on the element the onxyz attribute is on and (in some cases) various parents of it. That's what's happening to you: You're running into a situation where claer exists in that special scope because it exists on the element or its parent(s).

Instead, use addEventListener. It lets you use non-globals, and reliably attaches the precise function you give it. For instance, to do that with minimal changes to what you have:

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

Live Example:

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" >7</td>
    <td id="eight" >8</td>
    <td id="nine" >9</td>
    <td id="C" >C</td>
    <td id="AC">AC</td>
</tr>
</table>

(In modern coding, you'd probably have that in a module rather than a script, so that it isn't at global scope.)

But, ideally we wouldn't have to give each and every element an id like that and refer to them specifically. We could, for instance, use the number class you have on the digits:

for (const element of document.querySelectorAll(".number") {
    element.addEventListener("click", output);
}
document.getElementById("AC").addEventListener("click", clear);

Live Example:

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 >7</td>
    <td >8</td>
    <td >9</td>
    <td id="C" >C</td>
    <td id="AC">AC</td>
</tr>
</table>

CodePudding user response:

Just change the clear function name that will work

let result = document.getElementById("result");

function output() {
   result.innerHTML =  result.innerHTML   event.target.innerHTML;
}

function clearResult() {
  document.getElementById("result").innerHTML = "";
}

CodePudding user response:

The problem is "clear()" function already used by other thing, so you cannot use it, the fastest way to solve your problem is by changing the function name only. You could check my answer for this.

Other way to avoid it is actually just to wrap the function inside other thing, as you said you're still learning, so might as well show you the possibility. You could check this on my 2nd example.

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"  onclick = "calcOutput()">7</td>
        <td id="eight"  onclick = "calcOutput()">8</td>
        <td id="nine"  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"  onclick = "calculator.output()">7</td>
        <td id="eight2nd"  onclick = "calculator.output()">8</td>
        <td id="nine2nd"  onclick = "calculator.output()">9</td>
        <td id="C2nd" >C</td>
        <td id="AC2nd" onclick = "calculator.clear()">AC</td>
    </tr>
  </tbody>
</table>

  • Related