ant-design-vue 的 RangePicker 在 IE11 下 calendar panel 无法正常展开, 看图.
具体的相关讨论看参考链接中的 ant-design-vue 部分.
因为我知道 IE 和 Firefox,Chrome 下时间处理有问题 (es5 之前), 以为是 Date 的问题, 所以我的调试方向就走偏了, 顺便介绍下 Date.parse 的行为, new Date('字符串'), 内部使用 Date.parse 解析.
Date.parse 行为诡异
参考链接部分有大量的 Date 知识总结, 多多浏览.
Date.parse 在 ES5 之前不同浏览器, 行为差异很大. 现在我只能重现一下 IE 下的, Chrome 和 Firefox 版本都太高, 已经修正这个问题.
// 控制台 newDate('2019-07-02')// Tue Jul 02 2019 08:00:00 GMT+0800 (中国标准时间)newDate('2019/07/02')// Tue Jul 02 2019 00:00:00 GMT+0800 (中国标准时间)
看到区别了吗? time 部分, 一个从 0 点开始, 一个从 8 点开始, 为啥呢? 看看 MDN 怎么说吧.
MDN 文档不推荐在 ES5 之前使用 Date.parse 方法, 因为字符串的解析完全取决于实现. 直到至今, 不同宿主在如何解析日期字符串上仍存在许多差异, 因此最好还是手动解析日期字符串 (在需要适应不同格式时库能起到很大帮助).
注意: 如果你要兼容 IE, 对日期处理, 请使用专门的类库, 例如: moment.JS, day.JS 之类.
Date#toString()
顺便提一下, Date#toString() 竟然有规范, 看这里 Date.toString, 所以从 Date 字符串中解析提取一些字符可以放心大胆的用. 以后推荐使用 Intl 对象是 ECMAScript 国际化 API 的一个命名空间, 它提供了精确的字符串对比, 数字格式化, 和日期时间格式化
/** * 提取 GMT 时区 *@paramdate *@seehttps://developer.mozilla.org/en-US/docs/web/JavaScript/Reference/Global_Objects/Date/toString#Description *@returns''或者 GMT, 或者 GMT+0000 或者 GMT-0000; 其中 0000 代表 GMT 偏移量, 是四位前两位表示 hours 小时, 后两位表示 minuts 分钟. */functionextractTimezoneOffsetWithGMT(date){if(!date) {return''; }constdateTimeStr = date.toString();// Thu May 23 2019 14:52:15 GMT+0800 (中国标准时间)constgmtIndexStart = dateTimeStr.indexOf('GMT');consttimezoneEnd = dateTimeStr.indexOf(' ', gmtIndexStart);returndateTimeStr.substring(gmtIndexStart, timezoneEnd);}
placeholder 和 input 事件
和 ant-design-vue 维护者沟通之后, 得知这个 bug 在 ant-design-vue 的英文语言模式下不会有问题, 维护的小伙伴, 推测语言环境不同, 有可能导致编译的代码不同 (也有道理, 现在 JS 都上编译器, 你不知道编译后代码有多大变化, 当时已经提到了 placeholder, 我没注意).
思路: 英文版和中文版, 最大的不同应该是语言文件, 涉及到 RangePicker 只有 时间格式 和 placeholder , 时间格式已经怀疑过, 因为底层使用 moment 库处理, 所以没问题. 所以只能看看 placeholder 兼容性.
placeholder 兼容性
注意: 看下 Known issues 的 tab 页签, 看到第二条, 我震惊了, 为啥当 placeholder 为中文时会触发 input 事件???
input 事件的兼容性
重现 IE11 当 placeholder="中文" 时, 触发 input 事件
<!DOCTYPE html>placeholderwindow.onload =function(){varenInput =document.getElementById('en');varcnInput =document.getElementById('cn'); enInput.addEventListener('input',function(evt){console.log('en inpu'); }); cnInput.addEventListener('input',function(evt){console.log('cn input'); }); }
临时处理方案
知道了原因就很容易处理了, 只要 input 的 placeholder="" 就搞定了, 虽然不好看, 总比有 bug 好.
<!-- 重置 placeholder, 因为默认有语言文件, placeholder 默认有文字的 -->
到这里才找到真正造成 RangePicker 问题的原因, 反馈给了 ant-desing-vue 维护小伙伴, 他们下次修复上线.
如果有想学习编程的初学者, 可来我们的前端直播授课群的哦: 571671034 里面免费送整套系统的前端教程!
来源: http://www.jianshu.com/p/ee79b34e7ab4