【筆記】移動端H5數字鍵台input type=number的處理(IOS和Android)

來源:互聯網
上載者:User

標籤:直接   type   ide   lin   val   none   href   efi   const   

在Vue中的項目,基於VUX-UI開發,一個常見的需求:

1、金額輸入框2、彈出數字鍵台3、僅支援輸入兩位小數,限制最大11位元,不允許0開頭  

 

第一,首先想到額就是在VUX-UI中制定type=number。--不可行

  VUX中的文檔和代碼說明,type=number不支援maxLength,會報錯,而且沒有正則替換的處理或者鉤子函數,只有輸入後提示校正資訊。

第二,基於VUX中XInput封裝,有如下問題

  1)兩層v-model,正則替換的值不會觸發input框渲染

  解決:currentValue賦值為foramttedValue,放入setTimeout(func ,0)中,讓input框先渲染為正則替換前的值,再渲染為替換後的值

    currentValue(val, oldVal) {      // 調用filter過濾資料      let formattedValue = this.filter(val);      if (this.type === ‘number‘) {        formattedValue = this.typeNumberFilter(formattedValue, oldVal);      }      if (val !== formattedValue || val === ‘‘) {        setTimeout(() => {          this.currentValue = formattedValue;        }, 0);      }      this.$emit(‘input‘, formattedValue);    },
View Code

  2)數字鍵台input type=number,會導致maxlength失效,無法限制長度

  解決:用slice(0, max)處理

      if (formattedValue.length > this.max) {        formattedValue = formattedValue.slice(0, this.max);      }
View Code

  3)數字鍵台input type=number ,連續輸入小數點...導致實際值和顯示值不一致

  解決:用原生的 inputElement.value = oldValue處理

      const inputEle = this.$children[0].$refs.input;      // TODO: 待大範圍驗證:處理連續輸入..後,type=number的input框會把值修改為‘‘的問題;fastclick導致type=number報錯      // 問題描述: 1.00. 不會觸發值改變,1.00.不會觸發值改變,1.00.【\d\.】都會把值修改為空白字串‘‘。hack處理的條件說明如下:      // 1、當校正後是空值,(因input=number,formattedValue為‘‘表明 原始newVal也為‘‘)      // 2、輸入框拿到的是空值(因input=number導致輸入框立即被賦予空值。點擊清除按鈕時,這裡input輸入框還是上次的值)      // 3、上次輸入大於兩位(避免最後一位無法刪除的問題。最後一位刪除時,oldVal.length === 1)      if (formattedValue === ‘‘ && inputEle.value === ‘‘ && oldVal && oldVal.match(/^(\d)[\d.]+/)) {        formattedValue = oldVal;      }      setTimeout(() => {        inputEle.value = formattedValue;      }, 0);
View Code

   4)IOS中數字鍵台有%$*等特殊字元

  解決:用原生的 inputElement.onkeydown監聽事件,非數字和退格和小數點直接return事件

  mounted() {    if (this.type === ‘number‘) {      const inputEle = this.$refs.xinput.$refs.input;      // eslint-disable-next-line      inputEle.onkeydown = (e) => {        const keyCode = e.keyCode;        if (!this.isBackspace(keyCode) && !this.isDot(keyCode) && !this.isNumber(keyCode)) {          // 其他按鍵          e.preventDefault();          e.stopPropagation();          return false;        }      };    }  }
View Code

 

第三,其他說明

  為什麼不用 type=tel?

    type=tel在ios中沒有小數點

 

第四,全部代碼

 

<template>  <XInput    :title="title"    :max="currentMax"    :min="currentMin"    :type="type"    v-model="currentValue"    @on-focus="onFoucus()"    @on-blur="onBlur()"    :show-clear="showClear"    :placeholder="placeholder"    ref="xinput">    <template v-if="$slots.label" slot="label"><slot name="label"></slot></template>    <template v-if="$slots.right" slot="right"><slot name="right"></slot></template>  </XInput></template><script>export default {  data() {    return {      currentValue: this.value,    };  },  computed: {    currentMax() {      return (this.type === ‘number‘) ? undefined : this.max;    },    currentMin() {      return (this.type === ‘number‘) ? undefined : this.min;    }  },  props: {    title: String,    max: Number,    min: Number,    type: String,    showClear: {      type: Boolean,      default: true,    },    placeholder: String,    value: [String, Number],    filter: {      type: Function,      default: (value) => {        let formattedValue = ‘‘;        const match = value.match(/^([1-9]\d*(\.[\d]{0,2})?|0(\.[\d]{0,2})?)[\d.]*/);        if (match) {          formattedValue = match[1];        }        return formattedValue;      },    }  },  watch: {    currentValue(val, oldVal) {      // 調用filter過濾資料      let formattedValue = this.filter(val);      if (this.type === ‘number‘) {        formattedValue = this.typeNumberFilter(formattedValue, oldVal);      }      if (val !== formattedValue || val === ‘‘) {        setTimeout(() => {          this.currentValue = formattedValue;        }, 0);      }      this.$emit(‘input‘, formattedValue);    },    value(value) {      this.currentValue = value;    },  },  methods: {    onFoucus() {      this.$emit(‘on-focus‘);    },    onBlur() {      this.$emit(‘on-blur‘);    },    typeNumberFilter(val, oldVal) {      const inputEle = this.$refs.xinput.$refs.input;      let formattedValue = val;      // 由於type=number不支援maxLength,用slice類比      if (formattedValue.length > this.max) {        formattedValue = formattedValue.slice(0, this.max);      }      // TODO: 待大範圍驗證:處理連續輸入..後,type=number的input框會把值修改為‘‘的問題;fastclick導致type=number報錯      // 問題描述: 1.00. 不會觸發值改變,1.00.不會觸發值改變,1.00.【\d\.】都會把值修改為空白字串‘‘。hack處理的條件說明如下:      // 1、當校正後是空值,(因input=number,formattedValue為‘‘表明 原始newVal也為‘‘)      // 2、輸入框拿到的是空值(因input=number導致輸入框立即被賦予空值。點擊清除按鈕時,這裡input輸入框還是上次的值)      // 3、上次輸入大於兩位(避免最後一位無法刪除的問題。最後一位刪除時,oldVal.length === 1)      if (formattedValue === ‘‘ && inputEle.value === ‘‘ && oldVal && oldVal.match(/^(\d)[\d.]+/)) {        formattedValue = oldVal;      }      setTimeout(() => {        inputEle.value = formattedValue;      }, 0);      return formattedValue;    },    isBackspace(keyCode) {      return keyCode === 8;    },    isDot(keyCode) {      return keyCode === 46 || keyCode === 110 || keyCode === 190;    },    isNumber(keyCode) {      return (keyCode >= 48 && keyCode <= 57) || (keyCode >= 96 && keyCode <= 105);    },  },  mounted() {    if (this.type === ‘number‘) {      const inputEle = this.$refs.xinput.$refs.input;      // eslint-disable-next-line      inputEle.onkeydown = (e) => {        const keyCode = e.keyCode;        if (!this.isBackspace(keyCode) && !this.isDot(keyCode) && !this.isNumber(keyCode)) {          // 其他按鍵          e.preventDefault();          e.stopPropagation();          return false;        }      };    }  }};</script>
View Code

 

【筆記】移動端H5數字鍵台input type=number的處理(IOS和Android)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.