表单验证报错:无法读取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>
问题根源
- 遍历范围错误:直接遍历
event.target(表单元素)会获取所有子节点,包括div、span、提交按钮等非目标表单控件。这些元素要么无id,要么对应的xxx-label不存在,导致document.getElementById(${element.id}-label)返回null,访问innerText时触发报错。 - 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
相关产品推荐
相关产品推荐

