5

Im learning html/css/js from a video tutorial. Im learning how to write js code ans i cant help to solve a problem. I hope you give me the solution guys. The problem is about add.EventListener. When i run the code in chrome, in console it shows:"app.js:11 Uncaught TypeError: Cannot read property 'addEventListener' of null" I hope solve this problem with your help. Thank you!

const computerScore = 0;
const userScore_span = document.getElementById("user-score");
const computerScore_span = document.getElementById("computer-score");
const scoreBoard_div = document.querySelector(".score-board");
const result_div = document.querySelector(".result");
const p_div = document.getElementById("p");
const r_div = document.getElementById("r");
const s_div = document.getElementById("s");

p_div.addEventListener('click', function(){
    console.log("hey you clicked p")
})

This is the javescript code - below will be the html code to see any mistakes...

<html>
    <head>
        <meta charset="utf-8">
        <title>Rock Paper Sicssors Game</title>
        <link href="style.css" rel="stylesheet" type="text/css">
        <script type="text/javascript"  src="app.js" charset="utf-8"></script>
    </head>
    <body>
        <header>
            <h1>Rock Paper Sicssors</h1>
        </header>

        <div class="score-board">
            <div id="user-label" class="badge">user</div>
            <div id="computer-label" class="badge">comp</div>
            <span id="user-score">0</span>:<span id="computer-score">0</span>
        </div>

        <div class="result">
            <p>Paper covers rock. You win!</p>
        </div>

        <div class="choices">
            <div class="choice" id="p">
                <img src="game.image/paper-img.jpg" alt="image" height="42" width="42">
            </div>
        </div>
        <div class="choices">
                <div class="choice" id="r">
                    <img src="game.image/rock-img.jpg" alt="image" height="42" width="42">
                </div>
            </div>
        <div class="choices">
                    <div class="choice" id="s">
                        <img src="game.image/siccsors-img.jpg" alt="image" height="42" width="42">
                    </div>
                </div>


                <p1 id="action-message">Make your move.</p1>

     </body>
</html>
M.Margjini
  • 53
  • 2
  • 2
  • 6

6 Answers6

26

This happens because you're including the file containing your JavaScript in the <head> section of your html file.

<script type="text/javascript"  src="app.js" charset="utf-8"></script>

That means the browser will try to execute this statement

const p_div = document.getElementById("p");

but will fail to do so because the element in question is defined in the <body> section later on. Try to move the <script> section to the end of the <body>.

obscure
  • 8,071
  • 2
  • 9
  • 30
  • thank you! I'm so use to adding the script in the header it never occurred to me that it's execution matters in that it can't do something until those elements exist! – boardkeystown Mar 29 '21 at 23:39
7

Here is how the browser is processing your page:

  1. Download all the HTML
  2. Go through the head and download app.js
  3. Execute app.js
  4. Build the dom from the html

I would recommend moving your script tag

<script type="text/javascript"  src="app.js" charset="utf-8"></script>

to the bottom of your body. Then the browser will ensure all the dom exists before executing your script.

Alternatively, you could do this in your script:

function init() {
    // your code
}

And this in your body:

<body onload='init()'>

Which will wait until the body is loaded to execute the code.

Dr_Derp
  • 998
  • 5
  • 16
3

This happens because you are linking your script in the <head> tag, and when the DOM is loading first loading the script and after the body with your html content. The script doesn't know about your element with id "p". You must put your script before to close the body tag like this:

<body>
...
<script src="app.js"></script>
</body>
Dr_Derp
  • 998
  • 5
  • 16
Christian Carrillo
  • 2,433
  • 2
  • 6
  • 12
  • I put my script tag at bottom of page on master layout, and extending the master layout on other page (laravel) but in still happend – Bariq Dharmawan Jun 15 '20 at 12:52
2

The error is that your javascript is executed before the DOM has been loaded, so document.getElementById() is returning undefined (this can occur if your <script> tag is in the document <head>)

You could:

  • move your <script> tag to the end of the document <body>,

  • or you can wrap your javascript context in a function that listens for the DOM to be loaded before executing.

<script type="text/javascript">
  document.addEventListener("DOMContentLoaded", function(event) {
      // - Code to execute when all DOM content is loaded. 
  });
</script>

if you're already using jQuery (which might not be in this case since you're doing a video tutorial):

$(document).ready(function() { /* code here */ });

you can find more examples of the onload events in this post: window.onload vs document.onload

mwelche
  • 31
  • 3
0

You can also add the word defer to your script tag

<script type="text/javascript"  src="app.js" charset="utf-8" defer></script>

It means that the browser will load your Javascript file but will not execute it before your HTML was downloaded.

Hike
  • 1
0

This could also work. You could leave the script in the header, just type "defer" at the end.

<script type="text/javascript"  src="app.js" charset="utf-8" defer></script>