You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

实现时间输入框开始时间晚于结束时间时的类min/max验证错误提示

实现时间输入框开始时间晚于结束时间时的类min/max验证错误提示

嗨,我懂你想要的效果——就是让「开始时间大于结束时间」这种情况,也能触发和浏览器默认min/max校验一模一样的原生错误提示,而不是自己写个普通弹窗或者文字提示对吧?下面我给你调整代码,用原生的约束验证API来实现这个需求:

<form id="timeForm">
  Morning start: <input id="morningTimeStartArea" type="time" name="morningTimeStart" min="" max="" value="08:00:00" />
  Morning end: <input id="morningTimeEndArea" type="time" name="morningTimeEnd" min="" max="" value="13:00:00" /><br>
  Afternoon start: <input id="afternoonTimeStartArea" type="time" name="afternoonTimeStart" min="" max="" value="13:00:00" />
  Afternoon end: <input id="afternoonTimeEndArea" type="time" name="afternoonTimeEnd" min="" max="" value="16:30:00" /><br>
  <input type="submit" name="submit" value="submit" />
</form>

<script>
  const timesOfDay = ["morning", "afternoon"];
  // 这里我把startTime/endTime调整为和timesOfDay匹配的2个元素,你可以根据实际需求修改内容
  const startTime = ["08:00:00", "13:00:00"];
  const endTime = ["13:00:00", "16:30:00"];

  // 初始化每个输入框的min/max属性,和你原来的逻辑一致
  timesOfDay.forEach((item, index) => {
    const startInput = document.getElementById(`${item}TimeStartArea`);
    const endInput = document.getElementById(`${item}TimeEndArea`);
    
    startInput.min = startTime[index];
    startInput.max = endTime[index];
    endInput.min = startTime[index];
    endInput.max = endTime[index];
  });

  // 定义单个时间段的校验函数
  function validateTimeRange(timePeriod) {
    const startInput = document.getElementById(`${timePeriod}TimeStartArea`);
    const endInput = document.getElementById(`${timePeriod}TimeEndArea`);
    
    const startValue = startInput.value;
    const endValue = endInput.value;

    // 必须先清除之前的错误信息!否则校验通过后浏览器还会认为有错误
    startInput.setCustomValidity("");
    endInput.setCustomValidity("");

    // 校验开始时间是否大于结束时间
    if (startValue && endValue && startValue > endValue) {
      startInput.setCustomValidity("开始时间不能晚于结束时间哦");
      endInput.setCustomValidity("结束时间不能早于开始时间哦");
      // 触发浏览器原生的错误提示,和min/max的提示样式完全一致
      startInput.reportValidity();
      endInput.reportValidity();
    }
  }

  // 给每个时间输入框添加实时监听,用户一修改就校验
  timesOfDay.forEach(item => {
    const startInput = document.getElementById(`${item}TimeStartArea`);
    const endInput = document.getElementById(`${item}TimeEndArea`);
    
    startInput.addEventListener("input", () => validateTimeRange(item));
    endInput.addEventListener("input", () => validateTimeRange(item));
  });

  // 表单提交时再做一次全局校验,防止用户绕过输入直接提交
  document.getElementById("timeForm").addEventListener("submit", (e) => {
    timesOfDay.forEach(item => validateTimeRange(item));
    // 如果表单有校验错误,阻止提交
    if (!document.getElementById("timeForm").checkValidity()) {
      e.preventDefault();
    }
  });
</script>

核心实现说明

咱们用了浏览器原生的约束验证API,这是实现和min/max提示风格一致的关键:

  1. setCustomValidity(message):给输入框设置自定义错误信息,只要参数不是空字符串,浏览器就会标记该输入框不符合约束
  2. reportValidity():手动触发浏览器的原生错误提示弹窗,样式和min/max的错误提示完全一致
  3. checkValidity():检查整个表单的约束是否全部满足,用来在提交时拦截非法内容

几个要注意的小细节

  • 每次校验前必须调用setCustomValidity("")清除旧错误,不然用户修正输入后浏览器还会保留之前的错误标记
  • 监听input事件可以实现实时校验,用户修改时间的瞬间就会触发提示
  • 表单提交时的二次校验是为了防止用户通过控制台修改DOM、绕过输入直接提交的情况
  • 你原来的startTimeendTime有5个元素,但timesOfDay只有2个,我这里调整成了匹配的长度,你可以根据自己的实际需求修改数组内容哦

火山引擎 最新活动