htmloutputgetelementbyid

Why is document.getElementById sending output to wrong HTML span field?


I am trying to write a simple in-browser dice roller. It generates two integars between 0 and 9, adds them to an array and combines them output a value between 00 and 99 (RollFinalOutput).

But when I tried to output the final value to the HTML page via document.getElementById, RollFinalOutput is shown as "undefined".

However, I found that RollFinalOutput would appear in other span fields that I did not specify in the document.getElementById code.

The document.getElementById HTML and JS code I used is below. The full (broken) code is in this codepen.

I've not had this problem before. As far as I can tell, the code below should work.

Can anyone advise me as to I've done wrong here? Thanks.

const FinalResultArray = [0, 0];
var RollFinalOutput;
var d100RollResult;
var d10RollResult;

function DisplayFinalResult() {
  RollFinalOutput = [FinalResultArray.join("")];

  document.getElementById("DiceResult").innerHTML = RollFinalOutput + " DiceResult span";
  document.getElementById("Text").innerText = RollFinalOutput + " innerText span";
  document.getElementById("HTML").innerHTML = RollFinalOutput + " innerHTML span";

}

function TestRoll() {
  Rolla1d100(0, 9);
  DisplayFinalResult();
}

function Rolla1d100(min, max) {
  d10RollResult = Math.floor(Math.random() * (max - min)) + min;
  d100RollResult = Math.floor(Math.random() * (max - min)) + min;
  FinalResultArray[0] = d100RollResult;
  FinalResultArray[1] = d10RollResult;
}
<h2>Dice roll result displayed using innerText:</h2>

<h3>Result (span id DiceResult): <span id="DiceResult">??</span></h3>
<h3>Result (span id Text): <span id="Text">??</span></h3>
<h3>Result (span id HTML): <span id="HTML">??</span></h3>

<p>document.getElementById('DiceResult').innerHTML <button onclick="document.getElementById('DiceResult').innerHTML = TestRoll()">Run TestRoll</button></p>

<p>document.getElementById('innerText').innerHTML <button onclick="document.getElementById('Text').innerHTML = TestRoll()">Run TestRoll</button></p>

<p>document.getElementById('innerHTML').innerHTML <button onclick="document.getElementById('HTML').innerHTML = TestRoll()">Run TestRoll</button></p>


Solution

  • The issue is how you are triggering your TestRoll() function. The function itself doesn't return a value, so your:

    onclick="document.getElementById('DiceResult').innerHTML = TestRoll()"
    

    Overwrites the value that has just been set inside DisplayFinalResult() with undefined.

    Essentially:

    1. TestRoll() is called
    2. The logic runs
    3. The contents of all 3 elements are modified using document.getElementById("...").innerHTML = ...
    4. The contents of the clicked element is modified again to equal the value returned by TestRoll() (Which is undefined)

    Modified example which just calls the function without using its returned value:

    const FinalResultArray = [0, 0];
    var RollFinalOutput;
    var d100RollResult;
    var d10RollResult;
    
    function DisplayFinalResult() {
      RollFinalOutput = [FinalResultArray.join("")];
    
      document.getElementById("DiceResult").innerHTML = RollFinalOutput + " DiceResult span";
      document.getElementById("Text").innerText = RollFinalOutput + " innerText span";
      document.getElementById("HTML").innerHTML = RollFinalOutput + " innerHTML span";
    
    }
    
    function TestRoll() {
      Rolla1d100(0, 9);
      DisplayFinalResult();
    }
    
    function Rolla1d100(min, max) {
      d10RollResult = Math.floor(Math.random() * (max - min)) + min;
      d100RollResult = Math.floor(Math.random() * (max - min)) + min;
      FinalResultArray[0] = d100RollResult;
      FinalResultArray[1] = d10RollResult;
    }
    <h2>Dice roll result displayed using innerText:</h2>
    
    <h3>Result (span id DiceResult): <span id="DiceResult">??</span></h3>
    <h3>Result (span id Text): <span id="Text">??</span></h3>
    <h3>Result (span id HTML): <span id="HTML">??</span></h3>
    
    <p>document.getElementById('DiceResult').innerHTML <button onclick="TestRoll()">Run TestRoll</button></p>
    
    <p>document.getElementById('innerText').innerHTML <button onclick="TestRoll()">Run TestRoll</button></p>
    
    <p>document.getElementById('innerHTML').innerHTML <button onclick="TestRoll()">Run TestRoll</button></p>