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

JS电影购票表单验证问题求助:未校验即提交订单

问题解决方案

一、修复表单验证逻辑

你当前的核心问题是表单校验未触发就执行了订单添加,本质是没利用好浏览器原生校验机制或事件绑定错误,按以下步骤调整:

  1. 修正表单与按钮结构
    把「Place Order」按钮放在<form>标签内部,并设置按钮类型为type="submit",确保触发表单的原生校验流程:

    <form id="orderForm">
      <input type="text" name="fullName" placeholder="姓名" required>
      <input type="email" name="email" placeholder="邮箱" required>
      <input type="number" name="ticketQty" min="1" max="8" placeholder="购票数量" required>
      <button type="submit">Place Order</button>
    </form>
    
  2. 绑定表单submit事件而非按钮click事件
    原生表单校验会在submit事件触发前自动执行,通过监听表单的submit事件,先判断校验状态再执行订单逻辑:

    const orderForm = document.getElementById('orderForm');
    orderForm.addEventListener('submit', function(e) {
      e.preventDefault(); // 阻止默认页面跳转
      
      // 检查是否通过原生校验
      if (!this.checkValidity()) {
        this.reportValidity(); // 触发浏览器默认的错误提示(如字段为空的气泡提示)
        return; // 校验不通过则终止后续逻辑
      }
      
      // 校验通过,执行订单添加操作
      addOrderToHistory();
      this.reset(); // 重置表单
    });
    
  3. 手动校验(可选,自定义提示用)
    如果不想用浏览器默认提示,可手动校验每个字段:

    function validateForm() {
      const fullName = document.querySelector('[name="fullName"]').value.trim();
      const email = document.querySelector('[name="email"]').value.trim();
      const ticketQty = parseInt(document.querySelector('[name="ticketQty"]').value);
      
      if (!fullName) {
        alert('请填写姓名');
        return false;
      }
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(email)) {
        alert('请输入有效的邮箱地址');
        return false;
      }
      if (isNaN(ticketQty) || ticketQty < 1 || ticketQty > 8) {
        alert('购票数量必须在1-8之间');
        return false;
      }
      return true;
    }
    

    在submit事件中调用validateForm(),返回true才继续执行订单逻辑即可。

二、实现订单历史持久化(刷新不丢失)

利用浏览器的localStorage存储订单数据,它会持久保存在用户本地,除非手动清除:

  1. 存储订单数据
    校验通过后,将订单信息转为JSON字符串存入localStorage:

    function addOrderToHistory() {
      // 收集订单数据(替换成你实际的变量)
      const orderData = {
        fullName: document.querySelector('[name="fullName"]').value,
        email: document.querySelector('[name="email"]').value,
        ticketQty: document.querySelector('[name="ticketQty"]').value,
        movieTitle: '选中的电影标题',
        posterUrl: 'OMDB获取的海报地址',
        orderTime: new Date().toISOString()
      };
      
      // 读取已有订单,无则初始化空数组
      let orderHistory = JSON.parse(localStorage.getItem('movieOrderHistory')) || [];
      orderHistory.push(orderData);
      // 存回localStorage
      localStorage.setItem('movieOrderHistory', JSON.stringify(orderHistory));
      
      // 更新页面订单历史展示
      renderOrderHistory();
    }
    
  2. 页面加载时恢复订单历史
    在页面初始化阶段,从localStorage读取数据并渲染到页面:

    function renderOrderHistory() {
      const orderContainer = document.getElementById('orderHistory');
      const orderHistory = JSON.parse(localStorage.getItem('movieOrderHistory')) || [];
      
      orderContainer.innerHTML = ''; // 清空容器
      
      // 遍历生成订单DOM元素
      orderHistory.forEach(order => {
        const item = document.createElement('div');
        item.innerHTML = `
          <h4>${order.movieTitle}</h4>
          <p>姓名:${order.fullName}</p>
          <p>邮箱:${order.email}</p>
          <p>购票数量:${order.ticketQty}</p>
          <img src="${order.posterUrl}" alt="${order.movieTitle}" width="100">
          <p>下单时间:${new Date(order.orderTime).toLocaleString()}</p>
          <hr>
        `;
        orderContainer.appendChild(item);
      });
    }
    
    // 页面加载完成后渲染历史订单
    document.addEventListener('DOMContentLoaded', renderOrderHistory);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:56:02