You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

报错原因

  1. inputAll包含了表单中的提交按钮(带.submit类的input),遍历到该按钮时,它的nextElementSibling为null,继续调用nextElementSibling.nextElementSibling触发空指针错误。
  2. 原代码逻辑冗余: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 11:14:58