最初是想要在H5頁面中輸入數(shù)字的時(shí)候調(diào)起數(shù)字鍵盤缰冤,且只能輸入數(shù)字和小數(shù)點(diǎn),并且小數(shù)點(diǎn)后最多保留兩位小數(shù)
實(shí)踐證明:
1.input:
type = 'number'時(shí)给僵, 當(dāng)輸入的為非法數(shù)字 例如包括-+等毫捣,則在取value的值時(shí)判斷為非數(shù)字就會將value自動置為‘’,
且在ios中number類型不能成功調(diào)起數(shù)字鍵盤帝际,需要使用pattern調(diào)取數(shù)字鍵盤蔓同,但是此時(shí)系統(tǒng)鍵盤沒有小數(shù)點(diǎn)
type = 'tel' 調(diào)起數(shù)字鍵盤 沒有number value為空的問題
同樣在ios沒有小數(shù)點(diǎn)
type = "text" pattern="[0-9]*" 在安卓無法調(diào)取數(shù)字鍵盤 ,在ios能調(diào)起數(shù)字鍵盤沒有小數(shù)點(diǎn)蹲诀,同時(shí)能輸入-+/
其他type 則能輸入字符等
2.ios原生的可以設(shè)置keyboard type = decimal pad . 這個(gè)樣子的只能用原生.
3.無法實(shí)現(xiàn)與web端一致的實(shí)時(shí)校驗(yàn) keydown + keyup == input H5只有input
4.前端自己定制鍵盤斑粱,存在安全性問題 且需要禁止系統(tǒng)鍵盤,并且使用disabled禁止之后 沒有光標(biāo)了也是一個(gè)問題
最終解決脯爪,在input的時(shí)候做校驗(yàn)则北,但不是實(shí)時(shí)校驗(yàn),因?yàn)檩斎胱址臅r(shí)候編輯完一串字符串點(diǎn)擊字符串才會觸發(fā)input痕慢,其實(shí)在pc端輸入中文也是如此:
<input type="text" class="numberInp" :placeholder="placeholder"
v-model.trim="inputNum" @input="saveNumberData" maxlength="20">
methods:
saveNumberData () {
this.checkFloatNumber(this.inputNum);
}
checkFloatNumber (val){
let reg = new RegExp(/^[0-9]+(.[0-9]{1,2})?$/);
let length_1 = val.length-1;
let length_2 = val.length-2;
if (val) { // 當(dāng)輸入了值
if (!reg.test(val)) { // 并且值不合法
if (reg.test(val.substr(0,length_1))) { // 如果除去最后一位前面的合法
if(val.charAt(length_1) == '.' && val.indexOf('.') == length_1) {
// 當(dāng)最后一位為小數(shù)點(diǎn)并且值中只有一個(gè)小數(shù)點(diǎn)尚揣,則保留值
this.inputNum = val;
} else {
// 否則去掉最后一位
this.inputNum = val.substr(0,length_1);
}
// 如果除去最后兩位前面的合法并且最后兩位都是小數(shù)點(diǎn),就去掉最后一位
} else if (reg.test(val.substr(0,length_2)) && val.charAt(length_1) == '.' && val.indexOf('.') == length_2) {
this.inputNum = val.substr(0,length_1);
// 否則
} else {
// 如果值只有一位且是小數(shù)點(diǎn)掖举,或者值有兩位且是‘0.’快骗,則把值置為‘0.’
if(val == '.' || val.substr(0,length_1) == '0.'){
this.inputNum = '0.';
} else {
// 否則提示并清空
let instance = Toast('請輸入正確的數(shù)值');
setTimeout(() => {
instance.close();
this.inputNum = '';
}, 2000);
}
}
} else {
// 值合法的時(shí)候
// 如果第一位為0且第二位存在且第二位不是小數(shù)點(diǎn),提示并清空值
if(val.charAt(0) == 0 && val.charAt(1) && val.charAt(1) !== '.'){
let instance = Toast('請輸入正確的數(shù)值');
setTimeout(() => {
instance.close();
this.inputNum = '';
}, 2000);
} else {
// 否則保留值
this.inputNum = val;
}
}
}
}
下面是在研究過程中改造的自定義鍵盤組件:
<template>
<div class="pay-box" v-show="ifShowKB">
<div>
<!--keyboard-->
<transition name="slide">
<div class="key-box">
<div class="item v-1px-t">
<div class="key v-close"
@touchstart="close($event)"
@touchend="inputEnd($event)"
>關(guān)閉
</div>
</div>
<div class="item v-1px-t" v-for="(item, i) in keyList" :key="i">
<div class="key"
v-for="(val, key) in item"
:key="key"
@touchstart="inputStart(val, $event)"
@touchend="inputEnd($event)" :class="{'v-1px-l':key!=0}">
{{val}}
</div>
</div>
<div class="item v-1px-t">
<div class="key" style="background: #e8e8e8"
@touchstart="inputStart('.', $event)"
@touchend="inputEnd($event, 'dot')"
>.
</div>
<div class="key v-1px-l"
@touchstart="inputStart(0, $event)"
@touchend="inputEnd($event)"
>0
</div>
<div class="key v-1px-l" style="background: #e8e8e8"
@touchstart="del($event)"
@touchend="inputEnd($event,'del')"
>-
</div>
</div>
</div>
</transition>
</div>
</div>
</template>
<script>
export default {
name: 'vue-num-keyboard',
props: {
highlightColor: {// 高亮顏色
type: String,
default: '#ccc'
},
maxLength: { // 最大長度
type: Number,
default: 20
},
ifShow: {
type: Boolean,
default: false
}
},
data () {
return {
val: [],
keyList: [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
}
},
computed: {
ifShowKB () {
return this.ifShow;
}
},
methods: {
inputEnd (e, d) {
this.unhighLight(e.currentTarget, d)
},
// 恢復(fù)默認(rèn)
unhighLight (ele, d) {
if (d) {
ele.style.backgroundColor = '#e8e8e8'
} else {
ele.style.backgroundColor = '#fff'
}
},
// 高亮
highlight (ele) {
ele.style.backgroundColor = this.highlightColor
},
// 用戶輸入
inputStart (val, e) {
console.log(val, '輸入的值----------')
if (this.val.length <= this.maxLength) {
this.val.push(val);
console.log(this.val, '所有的值----------')
} else {
console.log(this.val, '最長----------')
}
this.$emit('numEnd', this.val.join(''));
// 設(shè)置高亮
this.highlight(e.currentTarget)
},
del () {
if (this.val.length > 0) {
this.val.pop()
}
this.$emit('numEnd', this.val.join(''));
},
close () {
this.$emit('hideKb');
}
}
}
</script>
<style lang='scss' rel="stylesheet/scss" type="text/css" scoped>
$keyH: .5rem;
$size: .18rem;
.pay-box {
box-sizing: border-box;
z-index: 500;
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 5*$keyH;
overflow-x: hidden;
overflow-y: hidden;
background-color: rgba(0, 0, 0, .5);
> div {
position: absolute;
width: 100%;
height: 5*$keyH;
left: 0;
bottom: 0;
background-color: #fff;
}
}
.v-1px-t, .v-1px-l, .v-1px {
position: relative;
}
.v-1px-t:before {
z-index: 112;
position: absolute;
left: 0;
top: 0;
right: 0;
height: 1px;
content: '';
border-top: 1px solid #c7c7c7;
transform: scaleY(.5);
color: #c7c7c7;
transform-origin: 0 0;
}
.v-1px-l:before {
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 1px;
content: '';
border-left: 1px solid #c7c7c7;
transform: scaleX(.5);
color: #c7c7c7;
transform-origin: 0 0;
}
.v-1px:before {
position: absolute;
left: 0;
top: 0;
width: 200%;
height: 200%;
content: '';
border: 1px solid #c7c7c7;
transform: scale(.5);
color: #c7c7c7;
transform-origin: left top;
}
/*鍵盤盒子*/
.key-box {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
font-size: $size;
color: #363636;
.item {
display: flex;
text-align: center;
line-height: $keyH;
height: $keyH;
}
.key {
cursor: pointer;
width: 100%;
height: 100%;
flex: 1;
}
.v-close {
text-align: right;
color: #4a90e2;
}
}
</style>