iOS软键盘调用遮挡问题及被撑起的页面无法回退到原来位置BUG解决方案

最近在写一个h5,大家都知道,移动端开发嘛,兼容问题是经常会遇到的,尤其是iOS,本人已经无力吐槽了。

虽然移动端安卓和iOS大部分内容都是兼容的,但是iOS还是有一些地方与安卓还是很有差异的,所以在开发过程中个人建议大家将iOS不兼容部分独立出来做处理。

今天本人就碰到了一个iOS的特殊bug,是输入框调起软键盘后输入框fixed定位失效被软件盘遮挡,发送消息过后软件盘占用部分无法正常回退的bug(6.7.4版本之后才会出现)

web.isIOS = function() {
        var isIphone = window.navigator.userAgent.toLowerCase().indexOf("iphone")>-1;
        var isIpad = window.navigator.userAgent.toLowerCase().indexOf("ipad")>-1;
        return isIphone || isIpad;
    }

以上方法是我用来检测iOS的方法

聊天信息代码

<template>
	<div id="secretMsg" ref="scrollEle">
		<ul class="secretMsgs" @click="inputBlur">
			<li v-if="item.type==1" v-for="item in list">
				<img class="secretMsgPhoto" :src="org.Logo" alt="" />
				<div class="myTime">{{item.createdAt}}</div>
				<p class="secretMsgContent">
					{{item.msg}}
				</p>
			</li>
			<li v-else class="formMe">
				<img class="secretMsgPhoto" :src="avatarUrl" alt="" />
				<div class="myTime">{{item.createdAt}}</div>
				<p class="secretMsgContent">
					{{item.msg}}
				</p>
			</li>
		</ul>
		<form action="javascript:return true" class="secretMsgbottomBtn">
			<input ref="commitInput"  type="text" placeholder="请输入您的问题..." name="" id="" v-model="commitVal" value="" />
			<div class="secretMsgbutton"  @click="msgEnter">发送</div>
		</form>
	</div>
</template>
<script>
	export default {
	  name: 'message',
	  data () {
	    return {
	    	 	avatarUrl:localStorage.getItem("avatarUrl") || "",
	      	displayName:localStorage.getItem("displayName") || "",
	    		commitVal:"",
	    		orgId:"",
	    		org:{},
	    		intervalMsg:null,
	    		list:[],
	    		lastMsgTime:"1970-09-06 14:18:11"
	  		}
		},
	  mounted:function(){
	  	this.orgId = this.$route.query.orgId
	  	this.getPrivateMsg(10000);
	  	this.overLook();
	  	this.intervalMsg = setInterval(this.getPrivateMsg,3000);
	  	this.axios.get("/api"//接口信息
				  	,{
				  		params:{
				  			orgid:this.orgId
				  		}
				  	}
			  	).then((res)=>{
			  		this.org = res.data.data;
			  		this.$emit("setTitle",res.data.data.OrgName)
			  	});
	  },
	  beforeDestroy:function(){
	  		clearInterval(this.intervalMsg);
	  		this.intervalMsg=null;
	  },
	  destroyed:function(){
	  	this.axios.get("/api").then((res)=>{//接口信息
	  		if(res.data.code==0){
	  			web.setCookie('unread',res.data.data.unread)
	  		}
	  	})
	  },
	  methods:{
	  	overLook:function(){
	  		this.axios.put("/api",{//接口信息
	  			type:'2',
	  			org:this.orgId,
	  			user:localStorage.getItem("userId")
	  		}).then((res)=>{
	  			
	  		})
	  		
	  	},
	  	getPrivateMsg:function(num){//获取私信列表
	  		this.axios.get("/api",{//接口信息
	  		params:{
	  			page:1,
	  			limit:num||20,
	  			type:2,
	  			org:this.orgId,
	  			user:localStorage.getItem("userId")
	  		}
		  	}).then((res)=>{
		  		if(res.data.code==0){
		  			   var lastMsgTime = this.lastMsgTime
			  		   var newMsg =	res.data.data.items.filter(function(i){//看看有没有新消息
			  				return (new Date(i.createdAt.replace(/\-/g, "/")).getTime() - new Date(lastMsgTime.replace(/\-/g, "/")).getTime()) > 0
			  			})
		  		   if(newMsg.length>0){
		  		   		this.overLook();
		  				window.setTimeout(()=>{//滚动到聊天信息底部
			            	 		this.$refs.scrollEle.scrollTop = this.$refs.scrollEle.scrollHeight
			         	},300)
		  				this.list = [...this.list,...newMsg];
				  		this.list.sort(function(a,b){
				  			return new Date(a.createdAt) - new Date(b.createdAt)
				  		})
				  		this.lastMsgTime = this.list[this.list.length-1].createdAt
		  		   }
		  			
		  		}
		  	});
	  	},
	  	msgEnter:function(){//发送新消息
	  		if(this.commitVal.Trim()==""){
	  			return;
	  		}
	  		this.axios.post("/api",{//接口信息
	  			type:2,
	  			user:localStorage.getItem("userId"),
	  			org:this.orgId,
	  			msg:this.commitVal
	  		}).then((res)=>{
	  				if(res.data.code==0){
	  					this.commitVal = "";
	  					this.getPrivateMsg();
	  					this.$refs.commitInput.blur();
	  					window.setTimeout(()=>{
			            	 		this.$refs.scrollEle.scrollTop = this.$refs.scrollEle.scrollHeight
			         	},300)
	  				}
	  				
	  		})
	  	}
	  }
	}
</script>

如果不做任何处理,安卓是正常的,但是iOS(6.7.4之后)就会出现输入框失去焦点后软件盘占用部分无法正常回退到底部。

本人的处理是将输入框部分的iOS聚焦部分单独处理

<input ref="commitInput"  @focus="iosInputFocus" type="text" placeholder="请输入您的问题..." name="" id="" v-model="commitVal" value="" />

方法:让页面滚动条跟随页面高度自动滚动(设置定时器是为了让软件盘的调用流畅)

iosInputFocus:function(){//处理iOS软键盘遮挡输入框
	if(web.isIOS()){
	  	setTimeout(()=>{
			document.body.scrollTop=document.body.scrollHeight
		 },400)
	}
},

同样的软件盘占用部分也是一个道理,本人的处理是在聚焦的时候设置值来监测用户输入,然后监听这个值的改变来控制页面滚动条的位置。

watch:{//处理iOS6.7.4之后软键盘关闭后页面无法回退到原来正常的位置
	 userInput: function( val ){
	       if(val){
		        setTimeout(()=>{
					document.body.scrollTop=document.body.scrollHeight
				},400)
	       }else{
		       setTimeout(() => {
                    const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0;
                    window.scrollTo(0, Math.max(scrollHeight - 1, 0));
                }, 100);
	       }
	  }
},
methods:{
    iosInputFocus:function(){//处理iOS软键盘遮挡输入框
          this.userInput=true
          if(web.isIOS()){
	      setTimeout(()=>{
		     document.body.scrollTop=document.body.scrollHeight
	      },400)
	 }
    },
    msgEnter:function(){//发送新消息
            this.userInput=false
	  		if(this.commitVal.Trim()==""){
	  			return;
	  		}
	  		this.axios.post("/api/privateMsg",{
	  			type:2,
	  			user:localStorage.getItem("userId"),
	  			org:this.orgId,
	  			msg:this.commitVal
	  		}).then((res)=>{
	  				if(res.data.code==0){
	  					this.commitVal = "";
	  					this.getPrivateMsg();
	  					this.$refs.commitInput.blur();
	  					window.setTimeout(()=>{
			            	 		this.$refs.scrollEle.scrollTop = this.$refs.scrollEle.scrollHeight
			         	},300)
	  				}
	  				
	  		})
	  	}
}

以上就是本人对iOS软件盘调用回退失效bug的处理,有过有大佬有其他方案请多多指教。

猜你喜欢

转载自blog.csdn.net/tan1071923745/article/details/86481334