点击按钮切换div显示状态报Cannot read properties of null错误如何解决
错误原因
- 元素获取时机错误:你在JS初始化阶段就执行
const targetDiv = document.getElementById("userDetail"),此时Handlebars模板还未通过fetch请求拿到数据渲染插入DOM,页面中不存在该元素,因此targetDiv取值为null,点击时访问null.style就会抛出对应错误。 - 重复ID违规:你在Handlebars的列表循环中,给每个用户的详情div都设置了
id="userDetail",而HTML规范要求ID在整个文档中必须唯一,就算后续元素渲染完成,也只会匹配到第一个符合ID的元素,无法实现每个按钮控制对应自己所属的用户详情。
抛出的错误信息:
TypeError: Cannot read properties of null (reading 'style')
修复方案
分三个部分修改代码:
1 修改CSS代码
将ID选择器改为类选择器,适配后续HTML修改:
.userDetail { display: none; }
2 修改Handlebars模板代码
把详情div的ID改为class,同时给点击按钮传入当前元素本身作为参数:
<script id="user-list" type="text/x-handlebars-template"> <ul class="people_list"> {{#each usersList}} <li> <p class="">{{name}}</p> <img src={{avatar}} alt={{name}}> <!-- 把id改为class --> <div class="userDetail"> <p>Id: {{id}}</p> <p>Created at: {{createdAt}}</p> </div> <!-- 点击时传入当前按钮元素 --> <button onclick="handleClick(this)"> Detail </button> </li> {{/each}} </ul> </script>
3 修改JS代码
删除初始化时获取targetDiv的逻辑,修改点击处理函数,通过当前点击的按钮查找同级的详情div,同时补充初始行内样式为空的判断:
const userListEl = document.getElementById('user-list').innerHTML; const template = Handlebars.compile(userListEl); // 删除原来的 const targetDiv = document.getElementById("userDetail"); 这行代码 fetch("https://5dc588200bbd050014fb8ae1.mockapi.io/assessment") .then(response => response.json()) .then((data) => { var userData = template({ usersList: data }) document.getElementById('test').innerHTML = userData; }).catch((error) => { console.log(error) }) // 修复函数名拼写,接收按钮元素参数 const handleClick = (btnEl) => { // 查找当前按钮所属列表项内对应的详情div const targetDiv = btnEl.parentElement.querySelector('.userDetail'); // 补充空值判断,适配初始css类设置的隐藏状态 if (targetDiv.style.display === "none" || targetDiv.style.display === "") { targetDiv.style.display = "block"; } else { targetDiv.style.display = "none"; } };
内容的提问来源于stack exchange,提问作者Ahsan Hafeez
相关产品推荐
相关产品推荐

