一、问题描述:
问题1:iOS唤起软键盘,将页面顶出屏外,且无法自动回退到正常位置
详细描述:在开发H5页面时,会遇到这样的问题,在iPhone访问有提交按钮fixed在底部页面,且页面中有input框等可录入信息的元素时,点击input框唤起键盘,输入信息,这时候页面会被顶出屏外,且在点击键盘的完成按钮收起键盘时,页面不会回到原来正常的位置。
问题2:点击fixed在底部的提交按钮无反应
详细描述:遇到问题1时,先是大概分析了一下,然后一顿操作,没想到解决了问题1却带来的新问题;页面虽然可以回到正常位置,但点击fixed在底部的提交按钮无反应,只有滑动一下屏幕才能正常点击键盘高度位置以下的区域。
二、解决方案(代码基于Vue写的,思路可参考)
问题1解决方法:可以将该页面最外层元素position:fixed住,这样唤起键盘、收起键盘就可以回退到正常位置了,但是这样解决就会引起问题2,所以我这里使用另一种方法解决问题1:
1、将页面最外层元素position:absolute住,并将其宽高均设置为100%;
2、使用sticky footer布局将底部提交按钮固定在页面底部;
到这里我已经解决了问题1,代码基本是这样的(这里css我用的是stylus,其实都大同小异),注意:content-wrapper与btn-wrapper为同级元素。
<template>
<div class="wrapper">
<div class="content-wrapper clearfix">
<div>
<input @focus="inpFocus" @blur="inpBlur" placeholder="请输入姓名"/>
<input @focus="inpFocus" @blur="inpBlur" placeholder="请输入身份证号码"/>
</div>
</div>
<div class="btn-wrapper">
<div class="submit">提交</div>
</div>
</div>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
isCanScroll: false
}
},
methods: {
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../common/stylus/mixin.styl"
.wrapper
position: absolute
top: 0
left: 0
width: 100%
height: 100%
.content-wrapper
width: 100%
height: 100%
overflow: auto
padding-bottom: 50px // padding-bottom的距离与底部按钮占用高度相等
box-sizing: border-box
overflow: auto
.btn-wrapper
position: relative
clear: both
width: 100%
height: 50px // 与上面的padding-bottom相等
padding: 0 30px
box-sizing: border-box
margin-top: -50px // 与该元素高度相等
display: flex
justify-content: center
align-items: center
background-color: #F5F5F9
.submit
width: 100%
height: 40px
background-color: #0091fa
border-radius: 10px
font-size: 17px
color: #ffffff
.clearfix
display: inline-block
&::after
display: block
content: "."
height: 0
line-height: 0
clear: both
visibility: hidden
</style>
3、继续解决问题2,监听input框的focus和blur事件,并设置状态isCanScroll ,默认不可滚动。这里的代码我是基于vue写的,具体解决问题的思路可供参考。
4、思路:当页面中只要还有一个input框是focus的状态,那么,isCanScroll状态就为false,即不可滚动,否则,当页面所有input框失去焦点,isCanScroll状态就为true,然后监听isCanScroll状态,当其为true时,使用scrollIntoView()方法,讲最外层元素滚动到页面顶端。
完整代码如下:
<template>
<div ref="outerWrapper" class="wrapper">
<div class="content-wrapper clearfix">
<div>
<input @focus="inpFocus" @blur="inpBlur" placeholder="请输入姓名"/>
<input @focus="inpFocus" @blur="inpBlur" placeholder="请输入身份证号码"/>
</div>
</div>
<div class="btn-wrapper">
<div class="submit">提交</div>
</div>
</div>
</template>
<script type="text/ecmascript-6">
export default {
data() {
return {
isCanScroll: false
}
},
methods: {
inpFocus () {
this.isCanScroll = false
},
inpBlur () {
this.isCanScroll = true
}
},
watch: {
'isCanScroll' (value) {
if (value) {
this.$refs.outerWrapper.scrollIntoView()
}
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../common/stylus/mixin.styl"
.wrapper
position: absolute
top: 0
left: 0
width: 100%
height: 100%
.content-wrapper
width: 100%
height: 100%
overflow: auto
padding-bottom: 50px // padding-bottom的距离与底部按钮占用高度相等
box-sizing: border-box
overflow: auto
.btn-wrapper
position: relative
clear: both
width: 100%
height: 50px // 与上面的padding-bottom相等
padding: 0 30px
box-sizing: border-box
margin-top: -50px // 与该元素高度相等
display: flex
justify-content: center
align-items: center
background-color: #F5F5F9
.submit
width: 100%
height: 40px
background-color: #0091fa
border-radius: 10px
font-size: 17px
color: #ffffff
.clearfix
display: inline-block
&::after
display: block
content: "."
height: 0
line-height: 0
clear: both
visibility: hidden
</style>
最后,我测试了iOS出现这样问题的情况,iOS浏览器中且页面内容未满一屏时会出现这样的情况,支付宝中打开没有这样的情况,应该是支付宝对这类问题进行了处理。