金额输入框 在 hybrid 下 iosandroid h5 处理情况

金额输入框 在 hybrid 下 iosandroid h5 处理情况,第1张

概述目标 做一个金额输入框 要求 只需输入 数字 或者 小数点不准输入非法数字 如 1.1. 或者 1..2数字最大输入到两位小数 如 1.22, 不可输入 1.222 此时我们只讨论系统键盘。 自定义键盘不可取因为输入框不能获取焦点, 自定义键盘需要搭配特定的输入框也就是没有光标的那种才合适 解决方案的常规手段无外乎一下三种 监听 keyup/keydown/keypress 目标

做一个金额输入框

要求
只需输入 数字 或者 小数点不准输入非法数字  如  1.1.  或者 1..2数字最大输入到两位小数  如  1.22,    不可输入 1.222 此时我们只讨论系统键盘。 自定义键盘不可取因为输入框不能获取焦点, 自定义键盘需要搭配特定的输入框也就是没有光标的那种才合适
解决方案的常规手段无外乎一下三种 监听 keyup/keydown/keypress 事件 通过 event.keycode 判断keycode的值来 return false还是true 此种体验最优,页面没有闪动 ( 存在部分兼容性) 监听 keyup/keydown/keypress 事件 通过 event.target.value 得到当前输入的值 通过 正则匹配来过滤是否替换为空 ( 存在部分兼容性)

监听 input 事件 通过 event.target.value 得到当前全部的输入值,但是当用户移动光标后在输入无法得知当前输入的是什么值, ( 完全兼容,但是没有什么乱用)

所以解决方案只有通过第一条或者第二条

在分析一下 input type 的取值 type =text d出的非数字键盘 体验最差 有限排除 type = number d出数字键盘,缺点 event.target.value 只能取到被过滤后的数字 type= tel d出数字键盘 event.target.value 可以取到正确值, 但是在ios下d出的软键盘 没有‘.‘

先来一段小前提,一下为亲测

在中文状态下在keycode 都是229

AndroID手机 d出的软键盘默认为中文状态 所以code码 都是229 ios手机 d出的软键盘默认为英文文状态 所以code码可以用

androID手机无法监听到keypress事件,只可以监听到keyup keydown

ios手机在 <input type=tel> d出的软键盘 只有1-9 没有 ‘.’

<input type="number">这种形式 event.target.value 得到的值只有纯数字,也就是输入12.... 的时候 event.target.value =12

所以解决方案呼之欲出

在androID 下input type=tel监听 keyup事件, event.target.value 通过正则过滤输入 在ios下 input type=number 通过 keypress 事件 event.keycode 过滤输入,

部分参考 https://cloud.tencent.com/developer/article/1098877

一下是我对以上的一个简单实现

<template>  <x-cell    :title="label"    :isBordorBootom = 'isBordorBootom'    v-clickoutsIDe="doCloseActive"    :>    <div >      <textarea        @change="$emit('change',currentValue)"        ref="textarea"                :placeholder="placeholder"        v-if="type === 'textarea'"        :rows="rows"        :Disabled="Disabled"        :Readonly="Readonly"        v-model="currentValue">      </textarea>      <div  v-else >        <div >          <slot name="prefix"></slot>        </div>        <input          @change="$emit('change',currentValue)"          ref="input"                    :placeholder="placeholder"          :maxlength="maxlength"          :number="type === 'number'"          :type="type"          :          @focus="focus"          @blur="$emit('blur')"          :Disabled="Disabled"          :Readonly="Readonly"          :value="currentValue"          @keyup="handleKeyup"          @keypress="handleKeypress"          @input="handleinput">        <div        @click="handleClear"                v-if="!disableClear"        v-show="(currentValue !== '') && type !== 'textarea' && active">        <!-- <i ></i> -->          <img src="./[email protected]" >      </div>         <div >          <slot name="afterfix"></slot>        </div>      </div>  </div>  </x-cell></template><script>import XCell from '../../cell/src/cell';import ClickoutsIDe from '../../../src/utils/clickoutsIDe';import icon from '../../icon/src/icon'/** * mt-fIEld * @desc 编辑器,依赖 cell * @module components/fIEld * * @param {string} [type=text] - fIEld 类型,接受 text,textarea 等 * @param {string} [label] - 标签 * @param {string} [rows] - textarea 的 rows * @param {string} [placeholder] - placeholder * @param {string} [Disabled] - Disabled * @param {string} [Readonly] - Readonly * @param {string} [state] - 表单校验状态样式,接受 error,warning,success * * @example * <mt-fIEld v-model="value" label="用户名"></mt-fIEld> * <mt-fIEld v-model="value" label="密码" placeholder="请输入密码"></mt-fIEld> * <mt-fIEld v-model="value" label="自我介绍" placeholder="自我介绍" type="textarea" rows="4"></mt-fIEld> * <mt-fIEld v-model="value" label="邮箱" placeholder="成功状态" state="success"></mt-fIEld> */export default {  name: 'CommonFIEld',data() {    return {      active: false,currentValue: this.value    };  },directives: {    ClickoutsIDe  },props: {    type: {      type: String,default: 'text'    },rows: String,label: String,placeholder: String,Readonly: Boolean,Disabled: Boolean,disableClear: Boolean,state: {      type: String,default: 'default'    },value: {},attr: Object,isBordorBootom: {      type: Boolean,default: false    },FontSize: String,paddingleft: String,maxlength: Number  },components: { XCell,icon },methods: {    doCloseActive() {      this.active = false;    },handleinput(evt) {      this.currentValue = evt.target.value       console.log('handleinput:',evt)    },handleKeydown(evt) {      console.log('handleKeydown:',evt)      if (this.type === 'number') {        const keyCode = evt.keyCode;        const inputVal = this.$refs.input.value        if (this.isNotNumberKeycode(keyCode) || this.isDotStart(keyCode,inputVal)) {          console.log('组织')          evt.preventDefault();          evt.stopPropagation();          return false;        }      }    },handleKeypress(evt) {      console.log('handleKeypress:',inputVal)) {          evt.preventDefault();          evt.stopPropagation();          return false;        }      }    },isBackspace(keyCode) {      return keyCode === 8;    },isDot(keyCode) {      return keyCode === 46 || keyCode === 190;    },isNumber(keyCode) {      return (keyCode >= 48 && keyCode <= 57);    },isDotStart(keyCode,inputVal) {      return this.isDot(keyCode) && (!inputVal || inputVal === '' || /\./.test(inputVal));    },isNotNumberKeycode(keyCode) {      return !this.isBackspace(keyCode) && !this.isDot(keyCode) && !this.isNumber(keyCode);    },handleKeyup(evt) {       console.log('handleKeyup:',evt)      if (this.type === 'number' || this.type === 'tel') {        let val = evt.target.value        console.log('原来的val:',val)        val = val.replace(/[^\d.]/g,'') //清除“数字”和“.”以外的字符        val = val.replace(/\.{2,}/g,'.') //只保留第一个. 清除多余的 连续两个        val = val.replace('.','$#$').replace(/\./g,'').replace('$#$','.') //只保留第一个. 清除多余的 非连续两个        val = val.replace(/^(\-)*(\d+)\.(\d\d).*$/,'.') //只能输入两个小数        if(val.indexOf('.')< 0 && val != ''){ //以上已经过滤,此处控制的是如果没有小数点,首位不能为类似于 01、02的金额          val = parsefloat(val)        }        console.log(val)        // this.currentValue = evt.target.value.replace(/[^\d]/g,'');        this.currentValue = val      }    },handleClear() {      if (this.Disabled || this.Readonly) return;      this.currentValue = '';      this.$emit('handleClear')    },focus() {      this.active = true      this.$emit('focus')    }  },computed: {    iconState() {      if (this.state === 'default') {        return ''      } else if (this.state === 'error') {        return ''      } else if (this.state === 'warning') {        return ''      } else if (this.state === 'success') {        return ''      } else {        return ''      }    },showClear() {          }  },watch: {    value(val) {      this.currentValue = val;    },currentValue(val) {      this.$emit('input',val);    },attr: {      immediate: true,handler(attrs) {        this.$nextTick(() => {          const target = [this.$refs.input,this.$refs.textarea];          target.forEach(el => {            if (!el || !attrs) return;            Object.keys(attrs).map(name => el.setAttribute(name,attrs[name]));          });        });      }    }  }};</script><style lang="sCSS" scoped>@import "../../../src/style/var.sCSS";input {  Font-family: The1Official_Bold ;}.mint-fIEld {  wIDth: 100%;}.mint-fIEld.is-textarea {    -webkit-Box-align: inherit;        -ms-flex-align: inherit;            align-items: inherit;}.input-waper {  // border-bottom: 1px solID #EEEEEE;  // padding: .3rem 0 .3rem 0;  border-bottom: 1px solID #A1A5B9;   padding-right: 5px;  display: flex;  // height: 1.1rem;  // padding: .28rem 0rem .27rem 0rem;  position: relative;  Box-sizing: border-Box;  .mint-fIEld-core {    border: 0;    padding: 0;    display: block;    wIDth: 100%;    resize: none;    Box-sizing: border-Box;    Font-size: .46rem;    outline:none;    color: $color-red;    padding-right: .5rem;  }  .prefix {    display: flex;    flex-direction: column;    justify-content: center;  }  .afterfix {       display: flex;    flex-direction: column;    justify-content: flex-end;    padding-bottom: .4rem;  }  ::-webkit-input-placeholder { /* WebKit browsers */    color: $color-red;    opacity: .5;  }  :-moz-placeholder { /* Mozilla firefox 4 to 18 */    color: $color-red;     opacity: .5;  }  ::-moz-placeholder { /* Mozilla firefox 19+ */    color: $color-red;     opacity: .5;  }  :-ms-input-placeholder { /* Internet Explorer 10+ */    color: $color-red;     opacity: .5;  }}// 去除number右侧箭头input::-webkit-outer-spin-button,input::-webkit-inner-spin-button {    -webkit-appearance: none !important;    margin: 0;}.mint-fIEld-clear {    display: flex;    justify-content: center;    align-items: flex-end;    padding-bottom: .4rem;    padding-right: .2rem;}.mint-fIEld-clear-img {  wIDth: 14px;  height: 14px;}.mint-fIEld-state {    color: inherit;    margin-left: 20px;}.mint-fIEld-state .mintui {    Font-size: 20px;}.mint-fIEld-state.is-default {    margin-left: 0;}.mint-fIEld-state.is-success {    color: #4caf50;}.mint-fIEld-state.is-warning {    color: #ffc107;}.mint-fIEld-state.is-error {    color: #f44336;}.mint-fIEld-other {    top: 0;    right: 0;    position: relative;}</style>
总结

以上是内存溢出为你收集整理的金额输入框 在 hybrid 下 ios/android h5 处理情况全部内容,希望文章能够帮你解决金额输入框 在 hybrid 下 ios/android h5 处理情况所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/998816.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存