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

SPA切换登录路由提交表单时触发Cannot read properties of null错误

问题分析与解决方案

错误原因

你遇到的Cannot read properties of null (reading 'addEventListener')错误,核心问题出在时机不匹配:

  • 首页的脚本在页面初始加载时就执行了document.querySelector("#userinfo"),但此时登录页的表单还未被加载到DOM中,导致form变量为null,调用addEventListener直接报错。
  • 就算后续切换到登录路由、表单成功加载,这段绑定事件的代码也不会重新执行,所以表单提交时监听器完全没触发。

解决方案

方案一:事件委托(推荐)

利用事件冒泡机制,把监听器绑定到页面始终存在的父元素(比如#main-page)上,不管表单什么时候加载,提交事件都会被捕获。

修改首页的脚本部分:

<script>
async function sendData(event) {
  event.preventDefault();
  console.log("I'm here 2");
  const outputElement = document.getElementById('output');
  outputElement.innerHTML = "change success";
}

// 绑定到持久存在的父元素,监听表单提交事件
document.getElementById('main-page').addEventListener("submit", (event) => {
  // 仅处理#userinfo表单的提交
  if (event.target.id === 'userinfo') {
    sendData(event);
  }
});
</script>

这种方式无需关心页面切换时机,一次绑定即可覆盖所有后续加载的表单,通用性更强。

方案二:路由加载完成后绑定事件

在路由的页面渲染逻辑中,判断当前路径为登录页时,再动态绑定表单事件。

修改router.js中的handleLocation函数:

const handleLocation = async () => {
    const path = window.location.pathname;
    const route = routes[path] || routes[404];
    const html = await fetch(route).then((data) => data.text());
    document.getElementById("main-page").innerHTML = html;

    // 仅在登录页加载完成后绑定表单事件
    if (path === '/login') {
        const form = document.querySelector("#userinfo");
        async function sendData(event) {
            event.preventDefault();
            console.log("I'm here 2");
            const outputElement = document.getElementById('output');
            outputElement.innerHTML = "change success";
        }
        form.addEventListener("submit", sendData);
    }
};

同时删除首页中原有的表单绑定脚本,避免初始加载时的报错和重复绑定问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 05:24:56