前端小糾結--自帶「歧視性」的IE11 input事件

第一次碰到自帶的歧視的bug,IE 11泥潭不解釋。javascript

原由

ant-design-vueRangePicker在IE11下calendar panel沒法正常展開,看圖。html

RangePicker

具體的相關討論看參考連接中的ant-design-vue部分。前端

由於我知道IE和firefox、chrome下時間處理有問題(es5以前),覺得是Date的問題,因此個人調試方向就走偏了,順便介紹下Date.parse的行爲,new Date('字符串'),內部使用Date.parse解析。vue

Date.parse行爲詭異

參考連接部分有大量的Date知識總結,多多瀏覽。java

Date.parse在ES5以前不一樣瀏覽器,行爲差別很大。如今我只能重現一下IE下的,Chrome和firefox版本都過高,已經修正這個問題。若是想看之前的兼容性問題,看這篇博客javascript-and-dates-what-messgit

// 控制檯
new Date('2019-07-02')
// Tue Jul 02 2019 08:00:00 GMT+0800 (中國標準時間)
new Date('2019/07/02')
// Tue Jul 02 2019 00:00:00 GMT+0800 (中國標準時間)
複製代碼

看到區別了嗎?time部分,一個從0點開始,一個從8點開始,爲啥呢?看看MDN怎麼說吧。github

MDN文檔不推薦在ES5以前使用Date.parse方法,由於字符串的解析徹底取決於實現。直到至今,不一樣宿主在如何解析日期字符串上仍存在許多差別,所以最好仍是手動解析日期字符串(在須要適應不一樣格式時庫能起到很大幫助)。chrome

注意:若是你要兼容IE,對日期處理,請使用專門的類庫,例如:moment.js, day.js之類。瀏覽器

Date#toString()

順便提一下,Date#toString()居然有規範,看這裏Date.toString,因此從Date字符串中解析提取一些字符能夠放心大膽的用。之後推薦使用Intl對象是 ECMAScript 國際化 API 的一個命名空間,它提供了精確的字符串對比、數字格式化,和日期時間格式化微信

/** * 提取GMT時區 * @param date * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toString#Description * @returns ''或者GMT,或者GMT+0000或者GMT-0000;其中0000表明GMT偏移量,是四位前兩位表示hours小時,後兩位表示minuts分鐘. */
function extractTimezoneOffsetWithGMT(date) {
  if (!date) {
    return '';
  }
  const dateTimeStr = date.toString(); // Thu May 23 2019 14:52:15 GMT+0800 (中國標準時間)
  const gmtIndexStart = dateTimeStr.indexOf('GMT');
  const timezoneEnd = dateTimeStr.indexOf(' ', gmtIndexStart);

  return dateTimeStr.substring(gmtIndexStart, timezoneEnd);
}
複製代碼

placeholder和input事件

ant-design-vue維護者溝通以後,得知這個bug在ant-design-vue的英文語言模式下不會有問題,維護的小夥伴,推測語言環境不一樣,有可能致使編譯的代碼不一樣(也有道理,如今js都上編譯器,你不知道編譯後代碼有多大變化,當時已經提到了placeholder,我沒注意)。

思路:英文版和中文版,最大的不一樣應該是語言文件,涉及到RangePicker只有時間格式placeholder,時間格式已經懷疑過,由於底層使用moment庫處理,因此沒問題。因此只能看看placeholder兼容性。

placeholder兼容性

caniuse-placeholder

注意:看下Known issues的tab頁籤,看到第二條,我震驚了,爲啥當placeholder爲中文時會觸發input事件???

input事件的兼容性

caniuse-input-event

重現IE11當placeholder="中文"時,觸發input事件

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>placeholder</title>
</head>
<body>
  <div id="content">
    <input type="text" placeholder="english" id="en">
    <input type="text" placeholder="中文" id="cn">
  </div>
  <script> window.onload = function () { var enInput = document.getElementById('en'); var cnInput = document.getElementById('cn'); enInput.addEventListener('input', function (evt) { console.log('en inpu'); }); cnInput.addEventListener('input', function (evt) { console.log('cn input'); }); } </script>
</body>
</html>

複製代碼

placeholder-fire-input-event

臨時處理方案

知道了緣由就很容易處理了,只要input的placeholder=""就搞定了,雖然很差看,總比有bug好。

<!-- 重置placeholder,由於默認有語言文件,placeholder默認有文字的 -->
 <a-range-picker @change="onChange" :placeholder="['', '']"/>
複製代碼

到這裏才找到真正形成RangePicker問題的緣由,反饋給了ant-desing-vue維護小夥伴,他們下次修復上線。

總結

解決問題的思路很重要,很重要,之後若是碰到IE下的問題,第一時間https://caniuse.com/網站看兼容性,被IE坑怕了,兼容IE,就是在浪費生命。

參考

Date.parse

阮一峯 JavaScript標準參考教程 Date對象

javascript-and-dates-what-mess

JS原生Date類型方法的一些冷知識

wxyyxc1992--時間與日期

IE11日曆選擇框有值的狀況沒法打開選擇框

ie11下組件DatePicker 日期選擇框不顯示且控制檯報錯

IE下點擊RangePicker會閃一下關閉,openChange執行3次

歡迎加入羣聊

若是入羣失敗,添加我的微信,拉你入羣,驗證消息:前端交流

關注公衆號,發現更多精彩內容。

相關文章
相關標籤/搜索