vue嵌套H5到APP,安卓键盘顶起页面内容错乱解决方案

1.h5嵌套到APP,input输入框页面被键盘顶起错乱
2.解决方案:不能使用定位,使用margin-top
3.如果想满屏兼容比如登陆页面 按钮在下面 不允许出现滚动则则需要手动计算margin-top的高度
4.需求 :登陆页面内嵌H5,兼容各个类型的手机不允许出现滑动,满屏展示

<template>
	<view class="box" :style="minHeight">
		<view @click="goBack">
			<u-icon name="close" size="32"></u-icon>
		</view>
		<view class="bolid-text">注册CCAPP账号</view>
		<view class="think-text">推荐使用手机验证码登录</view>
		<view class="phone-text">手机号</view>
		<view class="input-sty">
			<u-input v-model="user.phoneNo" type="number" border="none" placeholder="请输入手机号" />
		</view>
		<view class="valide-text">短信验证码</view>
		<view class="input-sty">
			<view style="width: 80%;">
				<u-input v-model="user.verifyCode" type="number" border="none" maxlength="6" placeholder="请输入验证码" />
			</view>
			<view>
				<tui-countdown-verify :seconds="90" :successVal="successVal" @send="send" :params="1" radius="70rpx"
					borderColor="#05CBA3" color="#05CBA3" :resetVal="resetVal">
				</tui-countdown-verify>
			</view>
		</view>
		<view class="shop" v-show="chanelFlag">
			渠道门店:{{channelName}}
		</view>
		<view class="registersIos" :style="{backgroundColor: text =='注册' ? '#04CBA3' :'#696969 ',marginTop: minHeight}" @click="goSubmit">
			{{text}}
		</view>
		<view class="xieyiIos">
			继续即表示您同意 <text style="color: #05CBA3;margin: 0 10rpx;text-decoration: underline;" @click="goProtocol">
				用户协议</text><text style="color: #05CBA3;margin: 0 10rpx;text-decoration: underline;"
				@click="goPrivacy">隐私条款</text>
		</view>
		<u-toast ref="uToast" />
	</view>
</template>

<script>
	// let wx1 = require("../../static/jweixin-1.6.0")
	import {
		ajax
	} from '@/ajax.js';
	import {
		setPageMinHeight
	} from '@/fn.js'
	import tuiCountdownVerify from "@/components/tui-countdown-verify.vue";
	import {
		loading,
		hideLoading,
	} from "@/fn.js";
	export default {
		components: {
			tuiCountdownVerify,

		},
		data() {
			return {
				uid: "",
				value: '',
				successVal: 0,
				iswx: false,
				resetVal: 0,
				channelName: '',
				text: '注册',
				user: {
					phoneNo: '',
					verifyCode: '',
					sharePhoneNo: '',
				},
				chanelFlag: false,
				system:'',
				minHeight:0
			}
		},
		mounted() {
			this.minHeight = uni.getSystemInfoSync().windowHeight - 350 + 'rpx' // 重要代码!!!计算出注册按钮到上个盒子的margin-top距离
			console.log(this.minHeight)
		},
		onLoad(e) {
			if (e.uid) {
				this.uid = e.uid
			}
			this.system = this.detectOS()
			console.log(this.system)
			if (e.sharePhoneNo) {
				uni.setStorageSync('sharePhoneNo', e.sharePhoneNo) //分享者的手机号码
			}
			// this.getChannel()
			if (uni.getStorageSync('sharePhoneNo')) {
				this.getChannel()
				this.chanelFlag = true;
			}
			let ua = window.navigator.userAgent.toLowerCase();
			if (ua.match(/MicroMessenger/i) == 'micromessenger') {
				this.iswx = true;
			}
		},

		onReady() {
			this.refCode = this.$refs.uCode;
		},
		methods: {
			/*用户协议*/
			goProtocol() {
				uni.navigateTo({
					url: '/pages/agreement/agreement'
				})
			},
			/*隐私政策*/
			goPrivacy() {
				uni.navigateTo({
					url: '/pages/agreement/clause'
				})
			},
			/*返回上一级别*/
			goBack() {
				uni.navigateBack(1)
			},
			/*获取渠道*/
			getChannel() {
				let that = this;
				ajax("get", '/health/channel/getBySharePhoneNo/' + uni.getStorageSync('sharePhoneNo')).then(res => {
					console.log('cc')
					console.log(res)
					console.log(res.hasOwnProperty("data"))
					console.log('cc')
					
					if(res.hasOwnProperty("data")){
						that.channelName = res.data.channelName
					}else{
						that.channelName = uni.getStorageSync('sharePhoneNo')
					}
				})
			},
			handleLaunchFn(e) {
				alert('success', e)
			},
			handleErrorFn(e) {
				alert('fail', e);
			},
			handleReadyFn(e) {
				alert('fail', e);
			},
			openMini() {
				loading()
				ajax('get', '/applet/nav/toApplet/' + this.uid).then(res => {
					hideLoading()
					let cData = JSON.parse(res.msg)
					location.href = cData.openlink
				});
			},
			/*发送验证码*/
			send() {
				let that = this;
				let reg = /^1[3456789]\d{9}$/;
				if (this.user.phoneNo == '') {
					this.resetVal++;
					this.$refs.uToast.show({
						message: '请输入手机号码',
						duration: 500
					})
					return false;
				}
				if (!reg.test(this.user.phoneNo)) {
					this.resetVal++;
					this.$refs.uToast.show({
						message: '手机号码不正确',
						duration: 500
					})
					return false;
				}
				// that.$u.api.getCode({
				// 	data: {
				// 		user: {
				// 			mobile: that.user.mobile
				// 		}
				// 	}
				// }).then(res => {
				// 	that.successVal++;
				// 	that.$refs.uToast.show({
				// 		message: '验证码已发送',
				// 	})
				// }).catch(err => {
				// 	that.resetVal++;
				// })
				ajax("get", "/health/user/getVerifyCode", {
					phoneNo: that.user.phoneNo
				}).then(res => {
					that.successVal++;
					that.$refs.uToast.show({
						message: '验证码已发送',
					})
				})
			},
			/*注册*/
			goSubmit() {
				let that = this;
				that.user.sharePhoneNo = uni.getStorageSync('sharePhoneNo')
				if (that.text == '注册') {
					ajax("post", "/health/user/login", that.user).then(res => {
						that.successVal++;
						that.$refs.uToast.show({
							message: '注册成功',
						})
						if (that.iswx) {
							let timer = setTimeout(() => {
								clearTimeout(timer)
								let timer = null;
								uni.navigateTo({
									url: '/pages/browser/index?sharePhoneNo='+ that.user.sharePhoneNo
								})
							}, 1000)
						} else {
							uni.navigateTo({
								url: '/pages/loadapp/loadapp?type=a&sharePhoneNo=' + that.user.sharePhoneNo
							})
						}
					}).then(res => {
						that.text = '注册成功'
					})
				} else {
					uni.navigateTo({
						url: '/pages/browser/index?sharePhoneNo='+ that.user.sharePhoneNo
					})
				}
			},
			/*判断页面是ios还是安卓*/
			detectOS() {
				var userAgent = navigator.userAgent || navigator.vendor || window.opera;

				// 检测iOS设备
				if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
					return 'iOS';
				}
				// 检测Android设备
				if (/Android/.test(userAgent)) {
					return 'Android';
				}
				// 如果不是iOS或Android,则返回其他
				return 'Other';
			},
		}
	}
</script>

<style scoped>
	.box {
		width: 100%;
		padding-top: 80rpx;
		padding-left: 76rpx;
		padding-right: 76rpx;
		box-sizing: border-box;
		height: 100vh;
		position: relative;
		/* overflow-y: scroll */
	}

	.bolid-text {
		font-family: PingFangSC, PingFang SC;
		font-weight: 800;
		font-size: 48rpx;
		color: #000000;
		margin-top: 74rpx;
	}

	.think-text {
		font-family: PingFangSC, PingFang SC;
		font-weight: 400;
		font-size: 24rpx;
		color: #B6B6B6;
		margin-top: 12rpx;
	}

	.phone-text {
		font-family: PingFangSC, PingFang SC;
		font-weight: 800;
		font-size: 32rpx;
		color: #000000;
		margin-top: 86rpx;
	}

	.valide-text {
		font-family: PingFangSC, PingFang SC;
		font-weight: 800;
		font-size: 32rpx;
		color: #000000;
		margin-top: 52rpx;
	}

	.input-sty {
		border-bottom: 2rpx solid #E6E6E6;
		display: flex;
		align-items: center;
		margin-top: 20rpx;
		padding-bottom: 16rpx;
	}

	.u-input {
		padding: 12rpx 0 !important;
	}

	.shop {
		box-sizing: border-box;
		margin-top: 62rpx;
		height: 96rpx;
		border-radius: 12rpx;
		border: 2rpx solid #04CBA3;
		font-family: PingFangSC, PingFang SC;
		font-weight: 600;
		font-size: 28rpx;
		color: #04CBA3;
		display: flex;
		justify-content: flex-start;
		align-items: center;
		word-break:break-all;
		padding-left: 20rpx;
		padding-right: 20rpx;
		box-sizing: border-box;
		background-color: #E5FAF5;
		position: absolute;
		top: 725rpx;
		left: 76rpx;
	}

	.registersAndro {
		width: 60%;
		height: 88rpx;
		border-radius: 12rpx;
		color: #FFFFFF;
		display: flex;
		justify-content: center;
		align-items: center;
		margin-top: 200rpx
	}
	
	.registersIos{
		width: 60%;
		height: 88rpx;
		border-radius: 12rpx;
		color: #FFFFFF;
		display: flex;
		justify-content: center;
		align-items: center;
		margin: 0 auto;
		/* margin-top: calc(100vh - 1000rpx); */
	}
	
	.xieyiAndro {
		font-family: PingFangSC, PingFang SC;
		font-weight: 400;
		font-size: 28rpx;
		color: #919191;
		margin: 40rpx auto 0;
		text-align: center;
	}
	.xieyiIos{
		font-family: PingFangSC, PingFang SC;
		font-weight: 400;
		font-size: 28rpx;
		color: #919191;
		text-align: center;
		width: 100%;
		margin-top: 52rpx;
	}
</style>
  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
感谢您的提问!以下是 Taro Ui Vue3 中防止 H5 安卓机在输入框弹窗键盘时将页面顶上去的一个例子: ``` <template> <div> <AtButton type="primary" @click="toggleModal">弹出模态框</AtButton> <AtModal :isOpened="isOpened" @close="handleClose"> <AtModalHeader>标题</AtModalHeader> <AtModalContent> <div class="input-wrapper"> <input type="text" placeholder="请输入内容" @focus="handleFocus" @blur="handleBlur"> </div> </AtModalContent> <AtModalAction> <Button onClick="handleClose">取消</Button> <Button onClick="handleClose">确定</Button> </AtModalAction> </AtModal> </div> </template> <script> import { defineComponent, onMounted, ref } from 'vue' import { AtButton, AtModal, AtModalHeader, AtModalContent, AtModalAction } from 'taro-ui-vue3' export default defineComponent({ name: 'ModalExample', components: { AtButton, AtModal, AtModalHeader, AtModalContent, AtModalAction, }, setup() { const isOpened = ref(false) const toggleModal = () => { isOpened.value = !isOpened.value } const handleClose = () => { isOpened.value = false } const handleFocus = () => { if (/Android/gi.test(navigator.userAgent)) { setTimeout(() => { document.activeElement.scrollIntoViewIfNeeded() }, 100) } } const handleBlur = () => { if (/Android/gi.test(navigator.userAgent)) { setTimeout(() => { document.activeElement.scrollIntoViewIfNeeded() }, 100) } } onMounted(() => { if (/Android/gi.test(navigator.userAgent)) { const height = window.innerHeight const timer = setInterval(() => { if (window.innerHeight !== height) { document.body.style.height = window.innerHeight + 'px' height = window.innerHeight } }, 100) return () => clearInterval(timer) } }) return { isOpened, toggleModal, handleClose, handleFocus, handleBlur, } }, }) </script> <style scoped> .input-wrapper { padding: 20px; } input { width: 100%; height: 50px; font-size: 18px; border: none; border-bottom: 1px solid #ccc; outline: none; } </style> ``` 这个例子中,我们使用了 Taro Ui Vue3 的 AtModal 组件,同时在输入框的 focus 和 blur 事件中,通过调用 `scrollIntoViewIfNeeded()` 方法,将输入框滚动到可视区域内。同时,在组件挂载时,我们通过监听窗口大小的变化,动态设置 body 的高度,以防止页面出现滚动条。希望这个例子能够帮到您!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值