Eventlistener is not working

Hi,
I have the error:
Uncaught ReferenceError: toggleDisplay is not defined

at the line:
closeX.addEventListener(‘click’, toggleDisplay);

why the first event attachment works?!

<!DOCTYPE html>
<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>Modal</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <button>click me</button>
    <div id="myModal" class="modal">
        <div class="modal-content">
            <span id="closeBtn">&times</span>
            <p>Hi...I ama a modal</p>
        </div>
    </div>
    <script src="script.js"></script>
</body>
</html>
var modal = document.getElementById('myModal')
var closeX = document.getElementById('closeBtn')
var modalBtn = document.querySelector('button')

modalBtn.addEventListener('click', toggleDiplay);
closeX.addEventListener('click', toggleDisplay);

function toggleDiplay(){
    let style = window.getComputedStyle(modal);
    if(style.getPropertyValue('display')=='block') {
        modal.style.display = 'none'
    } else modal.style.display = 'block'
    

}

body {
    font-family: Arial, Helvetica, sans-serif;
    font-size: 18px;
    line-height: 1.7;
}

button {
    background-color: coral;
    padding: 10px;
    color: #fff;
}

button:hover {
    background-color: rgba(0,0,0,0.5);
}
.modal {
    display: none;
    position: fixed;
    left: 0;
    top: 0;
    z-index: 1;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.5)
}

.modal-content {
    background-color: #f4f4f4;
    margin: 20% auto;
    padding: 20px;
    width: 70%;
    box-shadow: 0 5px 8px 0 rgba(0, 0, 0, 0.2),
                0 7px 20px 0 rgba(0, 0, 0, 0.17);
}

#close {
    float: right;
    font-size: 30px;
    color: #ccc;
}

#close:hover {
    color: #000;
    /* text-decoration: none; */
    cursor: pointer;
}

Have you tried to turn these two lines

modalBtn.addEventListener('click', toggleDiplay);
closeX.addEventListener('click', toggleDisplay);

into this

modalBtn.addEventListener('click', toggleDiplay());
closeX.addEventListener('click', toggleDisplay());

Spelling: you’ve called the function is toggleDiplay but you’re trying to call toggleDisplay

This is wrong: addEventListener takes a function as the second argument. If you call the function (toggleDisplay()), that means you are passing whatever value that function evaluates to instead

1 Like

@DanCouper I see!!! I’ve always wondered why the parentheses are sometimes needed; and sometimes just break everything. Thank you for pointing that out!!

1 Like

:slightly_smiling_face: I can remember being really confused as to why that didn’t work when I was first starting out, why I couldn’t do that. It took ages for it to click with me: a function always returns a value (and when there isn’t a return value defined, the return value is undefined). So whenever you see a function is being called, you replace it with whatever the return value is.

This is important to realise, cos it’s how the JS engine works. Program runs:

{Rest of my program}

It reaches that addEventListener function call. That’s what’s happening now, put it on top

addEventListener
{Rest of my program}

Evaluate that. It calls another function. Put that function on top

toggleDisplay
addEventListener
{Rest of my program}

Evaluate that, it’s a value, use that and pop the function off

addEventListener
{Rest of the program}

The event listener can now be evaluated to something. Do that, pop it off

{Rest of the program}

Carry on

3 Likes

This is the first time this has happened to me (posting a code with a typo) :sweat_smile:.
I guess there is no IDE or type of practice that can save you from that.
My apologies

1 Like

@DanCouper Wow thanks for the call stack breakdown! The subtle difference between referring a function and calling it only became apparent to me when I first worked on React. I noticed that when passing a method through props, this.functionName works while this.functionName() gives funky errors. Now I finally know why. Thanks again!