为什么我收到“无法读取 null 的属性“addEventListener”

时间:2021-02-19 03:55:13

标签: javascript addeventlistener

我想制作一个应用程序,我可以通过点击姓名来显示/隐藏我的学生数据。 我在点击姓名的地方使用了 addEventListener,然后它会添加一个类来显示学生数据。但我收到此错误 Uncaught TypeError: Cannot read property 'addEventListener' of null

有人知道为什么吗?我很感激你的帮助。谢谢。

这是我的 HTML 代码:

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

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

js代码:

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');
})

这是CSS:

.students-data{
    display: none;
}

.show{
    display: block;
}

2 个答案:

答案 0 :(得分:0)

您的操作顺序已关闭。在将其放入 dom 之前,您正在为学生姓名和数据定义 const。此外,您应该通过 querySelectorAll 方法运行这些,以便您可以在单击时获取每个节点列表进行迭代,因为 querySelector 将仅返回文档中与指定的 CSS 选择器集匹配的第一个元素。然后,您可以使用循环中的键来获取您单击的每个名称的数据信息,然后切换显示它的元素类。

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>

答案 1 :(得分:0)

首先,将您的 js 代码包装在 onload 事件中,当您开始运行选择器时,数据将准备就绪:

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

然后在使用 studentsName 添加学生部分后移动您的 innerHTML 选择器:

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

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

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

相关问题