一、写在前面
必须说明的是,在 Web 移动 项目 ( 也就是 webApp 项目,或是 App 内嵌 H5 项目 ) 中,进入登录页时,是无法自动唤起键盘的。原因是手机系统 安全机制的限制,所有H5页面上涉及到手机原生功能的操作,都必须有触发动作。也就是说如果想唤起手机自带键盘,就必须在输入框(或者页面)上点击一下,让输入框获得焦点,才可以。
因此,如果我们项目上为了提高用户体验,一定要在项目进入登录页时自动唤起键盘,只能自己画一个虚拟键盘来实现了。
此功能是在vue-cli脚手架上直接开发,仅仅是一个提高用户体验的功能,项目里用了 px2rem 插件来处理 px 单位,fastclick 来处理 ios 手机上 300 毫秒延迟,其余别的对本功能影响不大,所以直接上代码:
二、项目实现
第一步: 我们要把虚拟键盘画出来,这一步非常简单,做好布局就行
个人采用的是flex布局,也对flex进行了简单的兼容性处理、封装,
flex-->display:flex;
flex-wrap-->flex-wrap: wrap;
flex-center-->justify-content:center;
flex-vcenter-->align-items:center;
一行三个键,只有中间的那个有左右边框,要稍加注意。
<template>
<div ref="ul" class="list flex flex_wrap flex_center flex_end">
<ul v-for="(i,k) in keyBoard" :key="k" class="ul">
<li v-if="k!=11" class="li flex flex_center flex_vcenter" :class="{'BgG': k==9,'BorderLR': k==1||k==4||k==7||k==10}" @click="tapNum(i,k,$event)">{{i}}</li>
<li v-else class="li flex flex_center flex_vcenter BgG" @click="tapNum(i,k,$event)"><img class="deletImg" :src="i" /></li>
</ul>
</div>
</template>
<script>
export default {
data () {
return {
isShow: false,//加载提示,加载中,显示加载loadidng,加载完成,自动弹出键盘
deleteImg: '../../static/img/delete.png',//删除按钮图片,可以改成自己项目里的图片地址
keyBoard: [1,2,3,4,5,6,7,8,9,'',0,this.deleteImg],//显示的
}
},
……
}
</script>
第二步:
页面布局完成以后,其实已经大致可以实现虚拟键盘的功能,只需要在点击的时候记录下点击的键的值,作为字符串,如果是点击的删除图片,就把拼起来的字符串进行处理就可以了。
但是目前这样,点击的时候,页面没有任何反馈,页面是一个假死状态,用户可能不知道该点击动作是否有作用,体验非常不好,因此需要进一步处理。在用户点击(或者按下)某个键的时候,改变该键的背景色,点击结束(或者抬起键盘),背景色恢复,有了这个页面上的反馈,体验会更好一点。
在我们进行处理的时候发现,因为点击(click),是一个即时触发的动作,也就是说它是一个瞬间动作,而我们要实现的是按下改变背景色,抬起恢复背景色,所以需要我们去监听按下(touchstart)抬起(touchend)这两个动作:
<script>
export default {
methods: {
// 按下数字时,背景变色响应,抬起,恢复原背景色
changeBG() {
this.$refs.ul.addEventListener('touchstart',(e)=>{
console.log(1212)
let ev = e || event
let li = ev.target
if (li.className.indexOf('BgG') == -1) {
li.style.background = '#F2F2F2'
}
},false)
this.$refs.ul.addEventListener('touchend',(e)=>{
console.log(3434)
let ev = e || event
let li = ev.target
if (li.className.indexOf('BgG') == -1) {
li.style.background = '#FFF';
}
},false)
}
},
created () {
this.isShow = true
this.$nextTick(()=>{
this.changeBG()
})
},
}
在这一步里,我们尤其要注意2点:
第一:触发监听的动作,一定要在第一次点击动作之前。否则,第一次点击 ,页面上依然不会有任何反馈;
第二:触发监听时,此元素一定要在渲染完毕,页面上存在,否则,对不到监听对象,会报错;
因为在这里只是一个demo,我选择在created之后,定时一秒,让该元素渲染之后监听,此处用了 nextTick ,如果 nextTick 用法不清楚的童鞋,可以去官网再熟悉一下,这里不做过多的解释。
第三步: OK,到目前为止,已经差不多实现了虚拟键盘的自动唤起的功能,接下来我们要进行一些细节处理:比如加上一个键盘慢慢升起的动画:
<template>
<transition name="slide-up">
<section class="floatKeyBoard" v-if="isShow">
<div ref="ul" class="list flex flex_wrap flex_center flex_end">
<ul v-for="(i,k) in keyBoard" :key="k" class="ul">
<li v-if="k!=11" class="li flex flex_center flex_vcenter" :class="{'BgG': k==9,'BorderLR': k==1||k==4||k==7||k==10}" @click="tapNum(i,k,$event)">{{i}}</li>
<li v-else class="li flex flex_center flex_vcenter BgG" @click="tapNum(i,k,$event)"><img class="deletImg" :src="i" /></li>
</ul>
</div>
</section>
</transition>
</template>
<style scoped>
/* 设置持续时间和动画函数 */
.slide-up-enter-active {
transition: all .6s ease;
}
.slide-up-leave-active {
transition: all .6s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-up-enter, .slide-up-leave-to {
transform: translateY(100%);
opacity: 0;
}
</style>
再比如,键盘每次升起,随机改变[0-9]这几个数字的位置:
export default {
data () {
return {
num: [1,2,3,4,5,6,7,8,9,0],//虚拟数字键盘
keyBoard: [],//显示的
……
}
},
methods: {
// 虚拟键盘 数组洗牌
shuffle(array){
let i,x,j,end;
for(i = array.length; i > 0; i--){
j = Math.floor(Math.random() * i);
x = array[j];
array[j] = array[i-1];
array[i-1] = x;
if (i == array.length) {
end = array[i-1]
}
}
array = array.slice(0,-1)
let arr = ['',end,this.deleteImg]
this.keyBoard = array.concat(arr)
console.log(this.keyBoard)
return this.keyBoard
},
},
created () {
this.shuffle(this.num);
setTimeout(()=>{
this.isShow = true
this.$nextTick(()=>{
this.changeBG()
})
},1000)
},
}
三、over
到此,进入登录页面自动唤起键盘,这个小功能应该算是完美实现了。当然,我们在具体操作的时候,还可以美化一下键盘的样式,比如模拟出 ios 真实键盘的样式……等等,剩下的我们大家可以自己去摸索一下。这个只是我自己在优化项目的时候写出来的一个小功能,也是我第一次把自己的项目分享出来,写的不完美的地方,欢迎大家批评指正