JS Error: Uncaught Typeerror: Cannot read Property 'addeventlistener' of null

Asked

Viewed 2,761 times

3

I’m setting the function to open a menu. But I am getting the error message "Uncaught Typeerror: Cannot read Property 'addeventlistener' of null"

Below is the code I’m using to open the menu with JS

   var veri = 1;
var trigger = document.getElementById('menu-trigger').addEventListener("click",function(){
var menu = document.getElementById('menu-hidde');
if (veri == 1) {
    menu.style.left = "0px";
    veri = 0;
}else{
    menu.style.left = "-100%";
    veri = 1;
}
})

And also the HTML code where I quote the same

 <!DOCTYPE html>
<html lang"en">

<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="estilos.css" media="all" />
<script type="text/javascript" src="teste.js"></script>
<script defer src="https://use.fontawesome.com/releases/v5.0.9/js/all.js" integrity="sha384-8iPTk2s/jMVj81dnzb/iFR2sdA7u06vHJyyLlAd4snFpCl/SnyUjRrbdJsw1pGIl" crossorigin="anonymous"></script>
<title>Styles Conference</title>
</head>



<body>
<div class="menu-trigger" id="menu-trigger">
    <div></div>
    <div></div>
    <div></div>
</div>
<nav class="menu-hidde" id="menu-hidde">
	<ul>
		<li>teste</li>
		<li>teste</li>
		<li>teste</li>
		<li>teste</li>
	</ul>
</nav>

How can I fix this?

  • Look, I don’t know if your problem is here on the snippet or in a real app, but here on the snippet you posted, it’s two separate snippets. That is, js does not find the id it sent because they are not in the same context...

  • 1

    @Diegosantos I’m learning and found the codes in a snippet on the internet. It works perfectly but when I wrote it in Note Pad ++ presented this error.

  • Well, testing on a single snippet here worked for me. Show all the source your file... Other detail, did you call js before html or after? Prefer to call later or declare it in the header...

  • If applicable, use the window load event.

  • 1

    @Diegosantos updated my post showing my html completely, here is the link where I am taking the reference of the code https://preloadweb.wordpress.com/2016/03/09/menu-retratil-com-css-e-javascript/

  • Is your script the correct test.js? Replace with this and say what happens: '<script type="text/javascript" src="test.js" async></script>'

  • 1

    @Diegosantos It worked!! Thank you very much, where was my mistake?

  • I will answer... If you can dial as an answer, thank you

  • 1

    @dotSonic No, ascyn does not load later as Diego stated, he is mistaken ... the Async carries "asynchronously", which means there is no order, it may be that it works and may have occasion that fails, the correct is to use is defer or window.onload or DOMContentLoaded

  • @Guillhermenascimento, see that I put a comma "In this case" in my reply. This justifies my explanation.

  • 3

    Diego think this wrong (the downvote nay is mine) Async is not last, neither in this case nor in any, async is asynchronous, loads without defined order, as I explained in my reply, if the HTML is large you may have https://answall.com/a/289479/3635 - its response worked in the case of AP by coincidence only, in other environments or variations of download speed or small delays in web servers, ascyn can surely fail.

  • Agree @Guilhermenascimento. In fact async loads asynchronously. But as I said in this answer, exclusive to this problem, it carries last. Precisely because it is asynchronous. And it’s okay to downvote. Just like you’re here to add the community. Scoring is important to give us privilege. That’s why I asked in this case. But that’s part :D

  • 2

    No Diego, no last load, variations on the network and/or server will surely cause side effects, no order will not load exactly last, only last load because it is probably still testing on localhost, the moment you go to production (real site) and someone opening in a 3G with some oscillation will probably trigger the failure Cannot read Property 'addeventlistener' of null

Show 8 more comments

2 answers

4

You have to use or window.onload or document.addEventListener('DOMContentLoaded');, because the script loaded before the page and therefore the HTML elements did not exist yet.

So for example:

document.addEvent('DOMContentLoaded', function () {
    var veri = 1;
    var trigger = document.getElementById('menu-trigger').addEventListener("click",function(){
    var menu = document.getElementById('menu-hidde');
    if (veri == 1) {
        menu.style.left = "0px";
        veri = 0;
    }else{
        menu.style.left = "-100%";
        veri = 1;
    }
    });
});

Or you can use the attribute defer in it too, so:

<script defer type="text/javascript" src="teste.js"></script>

Similar to what you did in:

<script defer src="https://use.fontawesome.com/releases/v5.0.9/js/all.js" integrity="sha384-8iPTk2s/jMVj81dnzb/iFR2sdA7u06vHJyyLlAd4snFpCl/SnyUjRrbdJsw1pGIl" crossorigin="anonymous"></script>

That according to the kennel is supported by all modern browsers, defer will only execute the script when the document (DOM) is ready.

Async is different from Defer

The async attribute suggested in Diego’s reply does not work as stated:

The async attribute causes the browser to load its script, in this case, last. After HTML.

The async loads the file asynchronously, that is to say without synchronization, it can finish loading or executing before HTML, depending on the weight of the HTML page, that is to say it may fail.

The right thing would be to use defer that this yes will wait for the HTML content to be downloaded and the "parse" to be done and then yes the script runs.

0


In the import of your script:

<script type="text/javascript" src="teste.js"></script>

Switch to:

<script type="text/javascript" src="teste.js" async></script>

Motive:

Your js is running before HTML even loads into the browser. This way, it does not find the element you are looking for with the getElementById.

Just think: How could he add the Istener to a null object?

The attribute async, makes the browser load its script, in this case, last. After HTML.

  • 1

    "The async attribute causes the browser to load its script, in this case finally" - this statement is not correct and does not correspond to what the attribute async makes. Confirm yourself in documentation

  • 1

    As I said @Isac, there is a comma "In This Case"

  • 1

    The comma does not change the statement. The script may not be loaded last, depending on how the load is processed. It’s unlikely for a small example like the question, but possible.

  • 1

    Look, I don’t think it’s productive for us to be discussing the correct Portuguese or the importance of the comma in any sentence. But if the question is technical, let’s go: The reference is inside the header. When the browser receives the answer, it receives the js, with the async tag, it leaves to run the js after loading the DOM. Proof of this? How this script works. See for yourself. IN THIS CASE, async is running js after loading the DOM, in which case I used the word HTML to express myself...

  • Isac’s right about what he said. In fact, Async, as its name says, asymptotically loads, as I recall, it is not for internal scripts, but for external scripts, moreover, it does not expect the analysis of all elements, as would be the case with the IMG tag, certainly you wanted to talk about the Defer, this yes, does what you said.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.