JavaScript报错:Cannot read properties of null(reading 'classList') 求助
表单验证脚本报错修复方案
问题概述
表单功能符合预期,但控制台持续抛出以下错误:
Uncaught TypeError: Cannot read properties of null (reading 'classList') at script.js:41:51 at NodeList.forEach (<anonymous>) at script.js:35:12 at NodeList.forEach (<anonymous>) at errorForm (script.js:23:17) at script.js:16:7 at NodeList.forEach (<anonymous>) at HTMLInputElement.handleClick (script.js:13:12)
移除第二个nextElementSibling后报错消失,但提交已填表单时无法移除errorMessage,功能不符合预期,需解决报错且保留原有功能。
当前使用的脚本代码
const spanContainer = document.querySelectorAll(".form-container span"); const spanImg = document.querySelectorAll(".errorIcon") const submitBtn = document.querySelector(".submit"); const inputAll = document.querySelectorAll("form input"); const input = document.querySelector("input"); let formData = {}; // objeto para armazenar os dados do formulário input.addEventListener("input", function(event) { formData[input.name] = input.value; // atualiza o valor do objeto com o valor atual do input }); //input.addEventListener("input", errorForm); function handleClick(event) { inputAll.forEach((input) => { if(input.value === "") { event.preventDefault(); errorForm(); } }) } function errorForm() { spanContainer.forEach((span) => { if(span.innerText === ""){ span.classList.add("errorMessage"); } if(span.classList.contains("errorMessage")) { span.classList.add("error"); } spanImg.forEach((img) => { if(img.classList.contains("errorIcon")) { img.classList.add("selected"); } }) inputAll.forEach((input) => { if(input.classList.contains("submit") === false && input.value === "") { input.classList.add("error"); input.nextElementSibling.nextElementSibling.classList.add("error"); } else { input.classList.remove("error"); input.nextElementSibling.classList.remove("errorMessage"); input.nextElementSibling.classList.remove("selected"); input.nextElementSibling.nextElementSibling.classList.remove("error"); } }) }) } submitBtn.addEventListener("click", handleClick);
报错原因
inputAll包含了表单中的提交按钮(带.submit类的input),遍历到该按钮时,它的nextElementSibling为null,继续调用nextElementSibling.nextElementSibling触发空指针错误。- 原代码逻辑冗余:
spanContainer和spanImg的循环会重复触发inputAll遍历,导致不必要的DOM操作,同时错误状态的重置和添加逻辑混乱。
修复方案
修复后的代码
const spanContainer = document.querySelectorAll(".form-container span"); const spanImg = document.querySelectorAll(".errorIcon") const submitBtn = document.querySelector(".submit"); const inputAll = document.querySelectorAll("form input:not(.submit)"); // 直接排除提交按钮 const input = document.querySelector("input"); let formData = {}; // objeto para armazenar os dados do formulário input.addEventListener("input", function(event) { formData[input.name] = input.value; // atualiza o valor do objeto com o valor atual do input }); function handleClick(event) { let hasEmptyInput = false; // 先检查是否存在空输入框 inputAll.forEach((input) => { if(input.value.trim() === "") { hasEmptyInput = true; } }); if(hasEmptyInput) { event.preventDefault(); errorForm(); } } function errorForm() { // 先重置所有输入框的错误状态 inputAll.forEach(input => { input.classList.remove("error"); const errorImg = input.nextElementSibling; const errorMsg = input.nextElementSibling?.nextElementSibling; if(errorImg) { errorImg.classList.remove("selected", "errorMessage"); } if(errorMsg) { errorMsg.classList.remove("error"); } }); // 为空输入框添加错误样式 inputAll.forEach((input) => { if(input.value.trim() === "") { input.classList.add("error"); const errorImg = input.nextElementSibling; const errorMsg = input.nextElementSibling?.nextElementSibling; if(errorImg) { errorImg.classList.add("selected"); } if(errorMsg) { errorMsg.classList.add("error", "errorMessage"); } } }); } submitBtn.addEventListener("click", handleClick);
关键修复点
- 排除提交按钮:修改
inputAll选择器为form input:not(.submit),直接跳过提交按钮,避免遍历到无后续元素的DOM节点。 - 可选链运算符:使用
?.访问nextElementSibling.nextElementSibling,即使前一个节点为null也不会抛出错误。 - 优化逻辑顺序:先统一重置所有错误状态,再给空输入框添加错误样式,避免状态混乱。
- 空白字符处理:用
trim()判断输入值,避免用户仅输入空格被判定为有效输入。 - 移除冗余循环:删除不必要的
spanContainer和spanImg遍历,直接通过输入框关联对应的错误图标与提示文本,提升代码效率。
内容的提问来源于stack exchange,提问作者user21529408
相关产品推荐
相关产品推荐

