简体   繁体   中英

Why is my span element not updating after function call?

The Problem

I'm following an intro to JS course on Udemy. The course section is updating a span element by calling a JS function from a separate JS file. I figured I might be linking the scripts in the wrong order, but switching the order does nothing. Also, I know the file paths are right since an alert() function works fine. The file with the functions is imported before the file that calls it.

Edit I just realized that the console browser is giving me this error:

Uncaught TypeError: Cannot set properties of null (setting 'textContent')
    at outputResult (vendor.js:15:35)
    at app.js:5:1

I'm sure I'm making an obvious, rookie mistake. Any help diagnosing this would be appreciated.

Here's the HTML and JS files below. The 'vendor.js' file holds the functions, and 'app.js' calls them. I'm specifically trying to update the element with id='current-result' by calling the outputResult function located in 'vendor.js'. I'm expecting the element with that id to update to 10, as that is what I'm assigning to currentResult in app.js.

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Basics</title>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap"
      rel="stylesheet"
    />
    <link rel="stylesheet" href="assets/styles/app.css" />
    
    <script type="text/javascript" src="/Users/sailormetz/Software Development/Javascript/JSCourseMaterials/basics-01-starting-project/assets/scripts/vendor.js">
    </script>

    <script type="text/javascript" src="/Users/sailormetz/Software Development/Javascript/JSCourseMaterials/basics-01-starting-project/assets/scripts/app.js">
    </script>

  </head>
  <body>
    <header>
      <h1>The Unconventional Calculator</h1>
    </header>

    <section id="calculator">
      <input type="number" id="input-number" />
      <div id="calc-actions">
        <button type="button" id="btn-add">+</button>
        <button type="button" id="btn-subtract">-</button>
        <button type="button" id="btn-multiply">*</button>
        <button type="button" id="btn-divide">/</button>
      </div>
    </section>
    <section id="results">
      <h2 id="current-calculation">0</h2>
      <h2>Result: <span id="current-result">0</span></h2>
    </section>
  </body>
</html>

Vendor.js

const currentResultOutput = document.getElementById('current-result');
const currentCalculationOutput = document.getElementById('current-calculation');

function outputResult(result, text) {
  currentResultOutput.textContent = result;
  currentCalculationOutput.textContent = text;
}

app.js

let currentResult = 0

currentResult = currentResult + 10

outputResult(currentResult, '')

You are importing the Vendor.js at the top of the html file.

Inside the Vendor.js file, you are trying to access document.getElementById('current-result') and document.getElementById('current-calculation') . Will this be available inside Vendor.js ? No. Because these DOM elements will be available only once the DOM is loaded.

How to fix this?

You have to ensure that the DOM elements that you are trying to use are available while you are running the script

This can be fixed in two ways.

Option 1

Import Vendor.js at the bottom of body tag. This will loads the script file once the DOM has been loaded. So your dome elements with id 'current-result' and 'current-calculation' will be available inside Vendor.js file.

Like

<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  <title>Basics</title>
  <link href="https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap" rel="stylesheet" />
  <link rel="stylesheet" href="assets/styles/app.css" />

</head>

<body>
  <header>
    <h1>The Unconventional Calculator</h1>
  </header>

  <section id="calculator">
    <input type="number" id="input-number" />
    <div id="calc-actions">
      <button type="button" id="btn-add">+</button>
      <button type="button" id="btn-subtract">-</button>
      <button type="button" id="btn-multiply">*</button>
      <button type="button" id="btn-divide">/</button>
    </div>
  </section>
  <section id="results">
    <h2 id="current-calculation">0</h2>
    <h2>Result: <span id="current-result">0</span></h2>
  </section>
</body>
<!-- Import here -->
<script type="text/javascript"
  src="/Users/sailormetz/Software Development/Javascript/JSCourseMaterials/basics-01-starting-project/assets/scripts/vendor.js">
  </script>

<script type="text/javascript"
  src="/Users/sailormetz/Software Development/Javascript/JSCourseMaterials/basics-01-starting-project/assets/scripts/app.js">
  </script>

</html>

Option 2

Load scripts asychronously by ising async attribute in the script import. This will parse the script file only once the DOM content has been loaded.

Like

<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  <title>Basics</title>
  <link href="https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap" rel="stylesheet" />
  <link rel="stylesheet" href="assets/styles/app.css" />

  <script type="text/javascript" async
    src="/Users/sailormetz/Software Development/Javascript/JSCourseMaterials/basics-01-starting-project/assets/scripts/vendor.js">
    </script>

  <script type="text/javascript" async
    src="/Users/sailormetz/Software Development/Javascript/JSCourseMaterials/basics-01-starting-project/assets/scripts/app.js">
    </script>

</head>

<body>
  <header>
    <h1>The Unconventional Calculator</h1>
  </header>

  <section id="calculator">
    <input type="number" id="input-number" />
    <div id="calc-actions">
      <button type="button" id="btn-add">+</button>
      <button type="button" id="btn-subtract">-</button>
      <button type="button" id="btn-multiply">*</button>
      <button type="button" id="btn-divide">/</button>
    </div>
  </section>
  <section id="results">
    <h2 id="current-calculation">0</h2>
    <h2>Result: <span id="current-result">0</span></h2>
  </section>
</body>

</html>

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