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

表单验证报错:无法读取null的innerText属性问题求助

表单验证获取label文本时触发Null报错

在实现表单验证功能时,期望输入不满足要求时显示错误提示并复用label文本,但运行后控制台抛出错误:

Uncaught TypeError: Cannot read properties of null (reading 'innerText')
at onSubmit (app.js:40:71)
at HTMLFormElement.onsubmit (contact.html?userName=&userEmail=&userComment=:43:69)

尝试将label文本存入let label变量时,在访问.innerText时触发错误,相关代码如下:

JavaScript代码

'use strict';
const onSubmit = event => {
  event.preventDefault()
  for (let element of event.target)
    if (element.required) {
      let label = document.getElementById(`${element.id}-label`).innerText
      let error = ""
      switch (element.type) {
        case 'text':
          if (!isNullOrEmpty(element.value)) {
            if (!isMinLength(element.value, element.dataset.requiredMin)) {
              error = `Your ${label.toLocaleLowerCase()} must contain at least ${element.dataset.requiredMin} letters.`
            }
          } else {
            error = `You must enter a ${label.toLocaleLowerCase()}`
          }
          console.log('validera text');
          break;
        case 'email':
          console.log('validera email');
          break;
        case 'textarea':
          console.log('validera lösenord');
          break;
      }
      document.getElementById(`${element.id}-error`).innerText = error
    }
}

const isNullOrEmpty = value => {
  if (value.length === 0)
    return true

  return false
}

const isMinLength = (value, minLength = 2) => {
  if (value.length >= minLength)
    return true
  return false
}

HTML代码

<section class="form container">
  <h1>Come in Contact with Us</h1>
  <form onsubmit="onSubmit(event)" class="contact" novalidate>
    <div class="name_email">
      <span>
        <label id="userName-label" for="userName-input">Name</label>
        <input type="text" name="userName" id="userName-input" placeholder="Your Name" required data-required-min="2">
        <div id="userName-error"></div>
      </span>
      <span>
        <label id="userEmail-label" for="userEmail-input">Email</label>
        <input type="email" name="userEmail" id="userEmail-input" placeholder="Your Email" required>
        <div id="userEmail-error"></div>
      </span>
    </div>
    <div>
      <label id="userComment-label" for="userComment-input">Comments</label>
      <textarea type="text" name="userComment" id="userComment-input" placeholder="Comments" required data-required-min="10"></textarea>
      <div id="userComment-error"></div>
    </div>
    <div class="submitbutton">
      <button type="submit" class="button bg-red">Post Comments</button>
    </div>
  </form>
</section>

问题根源

  1. 遍历范围错误:直接遍历event.target(表单元素)会获取所有子节点,包括div、span、提交按钮等非目标表单控件。这些元素要么无id,要么对应的xxx-label不存在,导致document.getElementById(${element.id}-label)返回null,访问innerText时触发报错。
  2. textarea判断逻辑错误:textarea元素没有type属性,无法通过case 'textarea'匹配,导致验证逻辑失效。

修复方案

1. 修正遍历范围

使用表单的elements属性只遍历有效表单控件,而非所有子元素。

2. 增加空值校验

获取label元素后先判断是否存在,避免null报错。

3. 修正textarea判断逻辑

通过element.tagName判断textarea类型。

修改后的JavaScript代码:

'use strict';
const onSubmit = event => {
  event.preventDefault();
  // 仅遍历表单内的有效控件
  for (let element of event.target.elements) {
    if (element.required) {
      // 先获取label元素,判断是否存在
      const labelElement = document.getElementById(`${element.id}-label`);
      if (!labelElement) continue;
      const label = labelElement.innerText;
      let error = "";

      // 单独处理textarea类型
      if (element.tagName === 'TEXTAREA') {
        if (!isNullOrEmpty(element.value)) {
          if (!isMinLength(element.value, element.dataset.requiredMin)) {
            error = `Your ${label.toLowerCase()} must contain at least ${element.dataset.requiredMin} characters.`;
          }
        } else {
          error = `You must enter ${label.toLowerCase()}`;
        }
        console.log('validate textarea');
      } else {
        switch (element.type) {
          case 'text':
            if (!isNullOrEmpty(element.value)) {
              if (!isMinLength(element.value, element.dataset.requiredMin)) {
                error = `Your ${label.toLowerCase()} must contain at least ${element.dataset.requiredMin} characters.`;
              }
            } else {
              error = `You must enter a ${label.toLowerCase()}`;
            }
            console.log('validate text');
            break;
          case 'email':
            if (isNullOrEmpty(element.value)) {
              error = `You must enter your ${label.toLowerCase()}`;
            } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(element.value)) {
              error = `Please enter a valid ${label.toLowerCase()}`;
            }
            console.log('validate email');
            break;
        }
      }

      // 校验错误提示元素是否存在
      const errorElement = document.getElementById(`${element.id}-error`);
      if (errorElement) {
        errorElement.innerText = error;
      }
    }
  }
};

// 简化工具函数
const isNullOrEmpty = value => value.length === 0;
const isMinLength = (value, minLength = 2) => value.length >= minLength;

优化HTML

移除textarea的无效type="text"属性:

<textarea name="userComment" id="userComment-input" placeholder="Comments" required data-required-min="10"></textarea>

额外优化建议

  • 使用element.labels直接获取关联label,无需依赖id拼接,更健壮:
    const label = element.labels[0]?.innerText;
    
  • 为错误提示添加CSS样式,提升用户体验。

内容的提问来源于stack exchange,提问作者Elias

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 13:15:21