简体   繁体   中英

Need to reload page to make onclick function work in JS

I just created 2 days ago a script with Javascript, cause I'm learning it. The script basically calculate the missing elements on a Circle. For example, if I have a radius of 2, the script will return the diameter of 4, the circumference of 4π or I can have it to do 4 * Math.PI(so 4 * 3.14). Now the script basically works, except when I open the page for the first time and I put a value number in one of the input, and i click my button, "calcola"(sorry, it's in italian, i just want you to look at the core of the script) nothing happens, I have to reload the page 1 time or even 2 to see the results. And I don't know why. I think it's a cache problem or cause the browser or the js file can't get the value after the first page load... I have an external script file, and I've put it at the end of the html page, before the body tag closing. For the script part, here it is:

 window.onload = function() { var r = document.getElementById("raggio").value; var d = document.getElementById("diametro").value; var C = document.getElementById("circonferenza").value; var A = document.getElementById("area").value; var calc = document.getElementById("calc"); var rAtPow = new Number(); var rResult = document.getElementById("r"); var dResult = document.getElementById("d"); var CResult = document.getElementById("C"); var AResult = document.getElementById("A"); rResult.innerHTML = "Raggio:"; dResult.innerHTML = "Diametro:"; CResult.innerHTML = "Circonferenza:"; AResult.innerHTML = "Area:"; calc.onclick = function() { if (r.length > 0) { rAtPow = Math.pow(r, 2); d = r * 2; C = 2 * r * Math.PI; A = rAtPow * Math.PI; rResult.innerHTML = "Raggio:" + " " + r; dResult.innerHTML = "Diametro:" + " " + d; CResult.innerHTML = "Circonferenza:" + " " + C; AResult.innerHTML = "Area:" + " " + A; } else if (d.length > 0) { r = d / 2; C = d + "π"; rAtPow = Math.pow(r, 2); A = rAtPow + "π"; rResult.innerHTML = "Raggio:" + " " + r; dResult.innerHTML = "Diametro:" + " " + d; CResult.innerHTML = "Circonferenza:" + " " + C; AResult.innerHTML = "Area:" + " " + A; } else if (C.length > 0) { r = C / 2; d = C; rAtPow = Math.pow(r, 2); A = rAtPow + "π"; rResult.innerHTML = "Raggio:" + " " + r; dResult.innerHTML = "Diametro:" + " " + d; CResult.innerHTML = "Circonferenza:" + " " + C + "π"; AResult.innerHTML = "Area:" + " " + A; } else if (A.length > 0) { r = Math.sqrt(A); d = r * 2; C = 2 * r + "π"; rResult.innerHTML = "Raggio:" + " " + r; dResult.innerHTML = "Diametro:" + " " + d; CResult.innerHTML = "Circonferenza:" + " " + C; AResult.innerHTML = "Area:" + " " + A + "π"; } } }

The script works, but only after reloading the page 1 or even 2 times. Hope you will solve my problem.

The reason it isn't working is because the first part of your code, where you are reading the values the user has supplied, is run when the page is loaded, but not when the user click on the calc-button.

The reason it works when you reload the page, is because the browser fills in the empty boxes with the values it had last time.

If you change the values and click on calc, you the calculation is done with the old values.

If you change this code:

var r = document.getElementById("raggio").value;
var d = document.getElementById("diametro").value;
var C = document.getElementById("circonferenza").value;
var A = document.getElementById("area").value;

into this code:

var input = {
  r : document.getElementById("raggio"),
  d : document.getElementById("diametro"),
  C : document.getElementById("circonferenza"),
  A : document.getElementById("area")
}

And then in the first part of your click-handler have this:

calc.onclick = function() {
  var
    r = input.r.value,
    d = input.d.value,
    C = input.C.value,
    A = input.A.value;

  // ... the rest of your code ...
}

Then you will actually read the values when you click in the calc-button.

There are other things to that should be changed in the code. For example you have var rAtPow = new Number(); . You don't need to allocate a number in javascript. You can just declare the variable like var rAtPow; or var rAtPow=null; or even var rAtPow=NaN; You also repeat yourself a lot to output the result.

I assume that your HTML code for the output looks something like:

<div id="r"></div>
<div id="d"></div>
<div id="C"></div>
<div id="A"></div>

You could change it to something like this:

<div>Raggio: <output id="r"></div>
<div>Diametro: <output id="d"></div>
<div>Circonferenza: <output id="C"></div>
<div>Area: <output id="A"></div>

Then it is easy to translate without changing your code. It also makes the code much cleaner.

I refactored you code a bit.

HTML code (index.html)

<!doctype html>
<html>
  <head>
    <title>Stack overflow 32539264</title>
    <script src="index.js"></script>
  </head>
  <body>

    <div>
      <label>Raggio <input id="in_r"></label>
      <label>Diametro <input id="in_d"></label>
      <label>Circonferenza <input id="in_c"></label>
      <label>Area <input id="in_a"></label>
      <button id="calc">Calc</button>
    </div>

    <div>
      <div>Raggio: <output id="out_r"></div>
      <div>Diametro: <output id="out_d"></div>
      <div>Circonferenza: <output id="out_c"></div>
      <div>Area: <output id="out_a"></div>
    </div>

  </body>
</html>

and javascript (index.js)

document.addEventListener(
  "DOMContentLoaded",
  function(event) {
    var input = {
      r : document.getElementById("in_r"),
      d : document.getElementById("in_d"),
      C : document.getElementById("in_c"),
      A : document.getElementById("in_a")
    }

    var output = {
      r : document.getElementById("out_r"),
      d : document.getElementById("out_d"),
      C : document.getElementById("out_c"),
      A : document.getElementById("out_a")
    }

    var calc = document.getElementById("calc");
    calc.addEventListener(
      'click',
      function() {
        var
          r = input.r.value,
          d = input.d.value,
          C = input.C.value,
          A = input.A.value,
          rAtPow;

        if (r.length > 0) {
          rAtPow = Math.pow(r, 2);
          d = r * 2;
          C = 2 * r * Math.PI;
          A = rAtPow * Math.PI;
        } else if (d.length > 0) {
          r = d / 2;
          C = d + "π";
          rAtPow = Math.pow(r, 2);
          A = rAtPow + "π";
        } else if (C.length > 0) {
          r = C / 2;
          d = C;
          rAtPow = Math.pow(r, 2);
          A = rAtPow + "π";
        } else if (A.length > 0) {
          r = Math.sqrt(A);
          d = r * 2;
          C = 2 * r + "π";
        }
        output.r.value = r;
        output.d.value = d;
        output.C.value = C;
        output.A.value = A;
      }
    );
  }
);

Things to think about: there are no error handling in the code. You could make it more clear that you only use one of the input values by clearing the values that aren't used.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM