简体   繁体   中英

Why am i getting 'Cannot read property 'addEventListener' of null

I wanted to make an app where I can show/hide my students data by clicking on the names. I used addEventListener where I click on the names, then it'll add a class where it will show the students data. But I am getting this error Uncaught TypeError: Cannot read property 'addEventListener' of null

Anybody knows why? I appreciate the help. Thank you.

This is my HTML code:

<div class="container">
        <div class="hero">
            <h2>Students Data</h2>
        </div>

        <div id="output"></div>
</div>

The js code:

const output = document.getElementById('output')
const studentsName = document.querySelector('.students-name');
const studentsData = document.querySelector('.students-data');

const studentsList = [
    {
        name: 'John',
        january: 'Approved',
        february: 'Approved',
    },
    {
        name: 'Mike',
        january: 'Not Approved',
        february: 'Approved',
    },
    {
        name: 'Greg',
        january: 'Approved',
        february: 'Not Approved',
    },
    {
        name: 'Ash',
        january: 'Not Approved',
        february: 'Not Approved',
    }
]

const displayStudents = studentsList.map((student) => {
    return `
        <div class="students-name">
            <h3>${student.name}</h3>
            <div class="students-data">
                <li>January: ${student.january}</li>
                <li>February: ${student.february}</li>
            </div>
        </div>
    `
})
output.innerHTML = displayStudents.join('')

studentsName.addEventListener('click', () => {
    studentsData.classList.add('show');
})

And this is the css:

.students-data{
    display: none;
}

.show{
    display: block;
}

Your order of operations is off. You are defining your const for the student name and data before you place it into the dom. Also, you should run these through querySelectorAll method so you can get each nodelist for iteration on click as querySelector will only return the first element in the document that matches the specified set of CSS selectors. You can then use the key in the loop to get the data info for each name you click on, then toggle the elements class that shows it.

 const output = document.getElementById('output') const studentsList = [{ name: 'John', january: 'Approved', february: 'Approved', }, { name: 'Mike', january: 'Not Approved', february: 'Approved', }, { name: 'Greg', january: 'Approved', february: 'Not Approved', }, { name: 'Ash', january: 'Not Approved', february: 'Not Approved', } ] const displayStudents = studentsList.map((student) => { return ` <div class="students-name"> <h3>${student.name}</h3> <div class="students-data"> <li>January: ${student.january}</li> <li>February: ${student.february}</li> </div> </div> ` }) // here is where your innerHTML that includes the classes for // student-data and student-name // are being inserted into the DOM output.innerHTML = displayStudents.join(''); // now you can declare the variables that select the elements classes const studentsName = document.querySelectorAll('.students-name'); const studentsData = document.querySelectorAll('.students-data'); studentsName.forEach((student, i) => { student.addEventListener('click', () => { studentsData[i].classList.toggle('show'); }) })
 .students-data { display: none; }.show { display: block; }
 <div class="container"> <div class="hero"> <h2>Students Data</h2> </div> <div id="output"></div> </div>

First, wrap your js code inside an onload event, the data will be ready when you start running your selectors:

window.onload = (event) => {
  // js code
}

Then move your studentsName selectors after you add the student section with innerHTML :

output.innerHTML = displayStudents.join("");

const studentsName = document.querySelector(".students-name");
const studentsData = document.querySelector(".students-data");

demo: https://www.w3schools.com/code/tryit.asp?filename=GNSPS3ZG5KL0

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