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

为何设置datepicker非工作时段的JS函数会导致部分用户浏览器冻结

问题原因
  • 运算逻辑错误生成非法时间格式:你代码中'' + y.getHours() - 1 + ':'的运算顺序是从左到右,先执行字符串拼接得到字符串类型的小时值,再做减法会隐式转换为数字,当用户时区和你测试环境不一致时,getHours()可能返回0,最终会生成-1:59这类非法的时间值。绝大多数日期选择器组件拿到非法时间格式后,内部的时间遍历、校验逻辑会进入死循环,直接占满浏览器主线程,触发页面无响应提示。
  • 冗余规则放大性能损耗:invalid_a和invalid_b数组内的6个时间完全重复,map遍历后会生成12条完全相同的禁用规则,datepicker需要为每个渲染的日期校验所有规则,如果你配置的日期选择范围较大(比如展示半年/一年的日期),重复规则会成倍提升计算量,低配置设备很容易卡死。
  • 时区差异导致预期外的结果:你使用的是UTC格式的时间字符串,调用getHours()会转为用户本地时间计算,时区和你测试环境差异较大的用户(比如东西十二区),拿到的小时数可能超出0-23的合法范围,同样会触发组件内部逻辑异常。
优化后的实现方案

首先去掉无意义的重复遍历,修复运算优先级问题,统一时间格式避免非法值,优化后代码如下:

// 直接读取固定时段的小时值,无需重复解析相同时间字符串
// 如果你要使用本地时间,把getUTCHours替换为getHours即可
const workStartHour = new Date("2021-03-17T13:00:00.000Z").getUTCHours();
const workEndHour = new Date("2021-03-17T22:00:00.000Z").getUTCHours();
const workDays = ["MO", "TU", "WE", "TH", "FR", "SA"].join(',');

// 仅生成2条必要的禁用规则即可
const disableTimeRules = [
  // 禁用上班前时段
  {
    start: '00:00',
    end: `${String(workStartHour - 1).padStart(2, '0')}:59`,
    recurring: { repeat: 'weekly', weekDays: workDays }
  },
  // 禁用下班后时段
  {
    start: `${String(workEndHour).padStart(2, '0')}:01`,
    end: '23:59',
    recurring: { repeat: 'weekly', weekDays: workDays }
  }
];

console.log(disableTimeRules);
额外优化建议
  • 如果工作时段是固定值,不需要通过Date对象解析字符串获取小时,直接写死数值即可,性能更稳定。
  • 传入datepicker之前可以先校验时间格式合法性,保证小时范围在0-23、分钟在0-59,避免非法值传入组件。
  • 如果后续需要支持多套不同的工作时段,先对时间数组做去重处理后再遍历生成规则,避免生成重复冗余的规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 08:15:03