金额输入框 在 hybrid 下 ios/android h5 处理情况

编程之家收集整理的这篇文章主要介绍了金额输入框 在 hybrid 下 ios/android h5 处理情况编程之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

目标

一个金额输入框

要求

只需输入 数字 或者 小数点
不准输入非法数字  如  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 弹出的非数字键盘 体验最差 有限排除
  • type = number 弹出数字键盘,缺点 event.target.value 只能取到被过滤后的数字
  • type= tel 弹出数字键盘 event.target.value 可以取到正确值, 但是在ios下弹出的软键盘 没有‘.‘

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

  • 中文状态下在keycode 都是229

  • AndroID手机 弹出的软键盘认为中文状态 所以code码 都是229
  • ios手机 弹出的软键盘认为英文文状态 所以code码可以用
  • androID手机无法监听到keypress事件,只可以监听到keyup keydown

  • ios手机<input type=tel> 弹出的软键盘 只有1-9 没有 ‘.’
  • <input type="number">这种形式 event.target.value 得到的值只有纯数字,也就是输入12.... 的时候 event.target.value =12

所以解决方案呼之欲出

  • 在androIDinput 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"
    :class="[{
      'is-textarea': type === 'textarea','is-nolabel': !label
    }]">
    <div class="mint-fIEld">
      <textarea
        @change="$emit('change',currentValue)"
        ref="textarea"
        class="mint-fIEld-core"
        :placeholder="placeholder"
        v-if="type === 'textarea'"
        :rows="rows"
        :Disabled="Disabled"
        :Readonly="Readonly"
        v-model="currentValue">
      </textarea>
      <div class="input-waper" v-else >
        <div class="prefix">
          <slot name="prefix"></slot>
        </div>
        <input
          @change="$emit('change',currentValue)"
          ref="input"
          class="mint-fIEld-core"
          :placeholder="placeholder"
          :maxlength="maxlength"
          :number="type === 'number'"
          :type="type"
          :style="`Font-size:${FontSize}; paddingleft:${paddingleft}`"
          @focus="focus"
          @blur="$emit('blur')"
          :Disabled="Disabled"
          :Readonly="Readonly"
          :value="currentValue"
          @keyup="handleKeyup"
          @keypress="handleKeypress"
          @input="handleinput">
        <div
        @click="handleClear"
        class="mint-fIEld-clear"
        v-if="!disableClear"
        v-show="(currentValue !== '') && type !== 'textarea' && active">
        <!-- <i class="mintui mintui-fIEld-error"></i> -->
          <img src="./[email protected]" class="mint-fIEld-clear-img">
      </div>
         <div class="afterfix">
          <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).*$/,'$1$2.$3') //只能输入两个小数
        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>

解锁查看全部内容

付费后查看完整内容
限时 微信扫码支付 ¥9.9 19.9

总结

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

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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

Hybrid相关文章

tag,untag以及交换机的各种端口模式是网络工程技术人员调试交换机时接触最多的概念了,然而笔者发现在实际工作中技术人员往往对这些概念似懂非懂,笔者根据自己的理解再结合一个案例,试图向大家阐明这些概念 untag就是普通的ethernet报文,普通PC机的网卡是可以识别这样的报文进行通讯; tag报文结构的变化是在源mac地址和目的mac地址之后,加上了4bytes的vlan信息,也就是vlan
预备知识:Tag,untag以及交换机的各种端口模式是网络工程技术人员调试交换机时接触最多的概念了,然而笔者发现在实际工作中技术人员往往对这些概念似懂非懂,笔者根据自己的理解再结合一个案例,试图向大家阐明这些概念untag就是普通的ethernet报文,普通PC机的网卡是可以识别这样的报文进行通讯;tag报文结构的变化是在源mac地址和目的mac地址之后,加上了4bytes的vlan信息,也就是v
华为:Access、Hybrid和Trunk三种模式的理解预备知识: Tag,untag以及交换机的各种端口模式是网络工程技术人员调试交换机时接触最多的概念了,然而笔者发现在实际工作中技术人员往往对这些概念似懂非懂,笔者根据自己的理解再结合一个案例,试图向大家阐明这些概念 untag就是普通的ethernet报文,普通PC机的网卡是可以识别这样的报文进行通讯; tag报文结构的变化是在源mac地址
转自 http://blog.sina.com.cn/s/blog_3fcc38fc010007w4.html 1. Access端口 (1)收到一个二层帧 (2)判断是否有VLAN标签:没有则转到第3步,有则转到第4步 (3)打上端口的PVID,并进行交换转发 (4)若VLAN标签和PVID一致,转发VLAN帧;否则直接丢弃 2. trunk端口 (1)收到一个二层帧 (2)判断是否有VLAN标
以下是我对vlan的一点理解。   大家知道,交换机会把广播报文(目的mac地址全1的报文)和未知单播报文从所有端口转发出去(除了报文的接收端口),这就是广播。(对未知多播报文如何处理呢,我不知道,应该也会广播出去,这是一个遗留问题,哪位同学知道的请教教我哈)。一般交换机会发送很多广播报文,如果按照上面的处理方法,势必会影响整个网络的通信。vlan就是为了划分广播域而产生的。划分vlan之后,广播
关于Trunk、Hybrid、Access、Tag、Untag、Pvid的关系与区别 1、Trunk口,Trunk口上可以同时传送多个VLAN的包,一般用于交换机之间的链接。     2、Hybrid口,Hybrid口上可以同时传送多个VLAN的包,一般用于交换机之间的链接或交换机于服务器的链 接。     3、Access口,Access口只能属于1个VLAN,一般用于连接计算机的端口。    
以下是我对vlan的一点理解。 大家知道,交换机会把广播报文(目的mac地址全1的报文)和未知单播报文从所有端口转发出去(除了报文的接收端口),这就是广播。(对未知多播报文如何处理呢,我不知道,应该也会广播出去,这是一个遗留问题,哪位同学知道的请教教我哈)。一般交换机会发送很多广播报文,如果按照上面的处理方法,势必会影响整个网络的通信。vlan就是为了划分广播域而产生的。划分vlan之后,广播只在
  预备知识: Tag,untag以及交换机的各种端口模式是网络工程技术人员调试交换机时接触最多的概念了,然而笔者发现在实际工作中技术人员往往对这些概念似懂非懂,笔者根据自己的理解再结合一个案例,试图向大家阐明这些概念。 untag就是普通的ethernet报文,普通PC机的网卡是可以识别这样的报文进行通讯; tag报文结构的变化是在源mac地址和目的mac地址之后,加上了4bytes的vlan信
微信公众号搜索 “ 程序精选 ” ,选择关注!
微信公众号搜 "程序精选"关注