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

Laravel Blade表单JS验证报Cannot read properties of null错误

问题描述

在Laravel Blade模板中开发表单功能,使用JavaScript实现前端表单校验时,控制台抛出异常:
Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
相同校验逻辑在其他页面可正常运行,无法定位当前页面报错原因。

涉及的表单代码如下:

<form action="#" method = "POST">
    @csrf
    <div class="form-row">
        <div class="form-group col-lg-6 col-md-12 col-sm-12 col-12">
            <label for="first_name">First Name</label>
            <input type="text" id="fname" name = "first_name" class="form-control" placeholder="First Name" >
            <div id="namevalid" class="form-text text-muted invalid-feedback">
                Your name should be 3-15 characters long and shouldn't contain a number
            </div>
        </div>
        <div class="form-group col-lg-6 col-md-12 col-sm-12 col-12">
            <label for="last_name">Last Name</label>
            <input type="text" name = "last_name" class="form-control" placeholder="Last Name" required pattern="[a-zA-Z]([0-9a-zA-Z]){4,30}" min="4" max="30" title="Min 4 Max 30 Chars No Spaces No Special Charachters">
        </div>
        <div class="form-group col-lg-6 col-md-12 col-sm-12 col-12">
            <label for="subject">Subject</label>
            <input type="text" name = "subject" class="form-control" placeholder="Subject" required pattern = '[a-zA-Z]([0-9a-zA-Z]){4,50}' min="5" max="50" title="Max Length exceeded of 50 chars and Single Word Subject e.g wedding">
        </div>
    </div>
    <label for="email">Email</label>
    <input type="text" name ="email" class="form-control" placeholder="Email" required pattern="([a-zA-Z0-9_\-.]+)@([a-zA-Z0-9_\-.]+)\.([a-zA-Z]){2,7}" title="Only . allowed no Spaces no special characters">
    <label for="message">Your Message</label>
    <textarea name ="message" class="form-control mb-3" placeholder="Type Here" id="" cols="10" rows="5" required min="5" max ="5000" title="Message cannot be empty"></textarea>
    <button type = "submit" class="btn btn-success float-right">Send Message</button>
</form>

涉及的JavaScript校验代码如下:

const fname= document.getElementById('fname');
console.log(fname)

fname.addEventListener('blur', ()=>{
    console.log("first name is blurred");
    // First name Validation
    let regex = /^[a-zA-Z]$/;
    let str = fname.value;
    console.log(regex, str);

    if(regex.test(str)){
        console.log('First name is valid');
        fname.classList.remove('is-invalid');
    }
    else{
        console.log('Last name is not valid');
        fname.classList.add('is-invalid');
    }
})
报错根因

错误触发逻辑非常明确:执行document.getElementById('fname')时返回值为null,也就是JS代码运行的时机,页面DOM树里还不存在id为fname的输入框元素,对null值调用addEventListener方法就会抛出类型错误。

相同逻辑在其他页面能正常运行,核心原因是其他页面的JS代码要么放在了对应DOM元素的后方(浏览器解析到JS时已经完成前面DOM的渲染,能正常拿到元素),要么加了DOM加载完成的监听事件。当前页面的JS代码大概率放在了表单DOM的前面(比如head标签里、body最开头),浏览器从上到下解析页面时先运行了JS,此时下方的表单元素还没被解析加载,自然拿不到对应节点。

另外现有代码还有两处逻辑问题:

  • 校验正则/^[a-zA-Z]$/只能匹配单个英文字母,和提示文案里「3-15个字符、不能包含数字」的规则不匹配
  • 校验失败时的日志打印错误,把First name写成了Last name
修复方案

任选以下一种方案即可解决报错:

  • 方案1:把JS代码移动到</body>标签之前,也就是所有页面DOM元素的最后方,保证JS运行时所有DOM已经解析完成。
  • 方案2:给JS代码加上DOM加载完成的监听,等整个DOM树解析完毕再执行元素获取和事件绑定逻辑,修正后的JS代码如下:
// DOM全部加载完成后再执行绑定逻辑
document.addEventListener('DOMContentLoaded', function() {
    const fname= document.getElementById('fname');
    console.log(fname)

    fname.addEventListener('blur', ()=>{
        console.log("first name is blurred");
        // 修正正则,匹配3-15位纯英文字母,自动去除首尾空格
        let regex = /^[a-zA-Z]{3,15}$/;
        let str = fname.value.trim();
        console.log(regex, str);

        if(regex.test(str)){
            console.log('First name is valid');
            fname.classList.remove('is-invalid');
        }
        else{
            console.log('First name is not valid');
            fname.classList.add('is-invalid');
        }
    })
})
  • 额外排查点:如果用了Laravel的布局继承、组件语法,要确认当前页面没有出现id重复的情况,或者fname输入框被@if等条件语法包裹导致没有实际渲染到页面上,从贴出的代码判断这个概率极低,99%的场景都是JS加载时机错误导致的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 03:06:21