react在安卓下输入框被手机键盘遮挡问题

问题概述

  今天遇到了一个问题,在安卓手机上,当我要点击输入“姓名”时,手机软键盘弹出来把背景图片挤压变形了;整个手机窗口被压为原来的二分之一左右;

(左边一 效果图 )  (右边一安卓效果图)

完整代码

componentDidMount() {
    this.pageInputScroll()
  }
  pageInputScroll() {
    let that =this
    let initWindowHeight=window.innerHeight
    setTimeout(() => {
      let wrapDiv=document.getElementsByClassName('refer1')[0]
      //console.log(wrapDiv.style)
      wrapDiv.style.minHeight =initWindowHeight+'px'
    }, 500);
    //由于我们不能直接知道软键盘什么时候出来,不过软键盘出来的时候窗口高度会缩小,所以我们可以通过监听窗口大小变化事件来判断软键盘是否弹出
    window.onresize=function(){ //如果浏览器窗口高度缩小25%以上,就认为是软键盘出来了
      if(initWindowHeight-window.innerHeight>initWindowHeight/4&&document.querySelectorAll(':focus').length>0){
        if(that.offset(document.querySelectorAll(':focus')[0]).top>initWindowHeight/4){
          document.body.scrollTop=that.offset(document.querySelectorAll(':focus')[0]).top-initWindowHeight/4
        }
      }else if(window.innerHeight-initWindowHeight<20){
        document.body.scrollTop=0
      }
    };
  }
  offset(element) {
    var offest = {
      top: 0,
      left: 0
    };
    var _position;
    getOffset(element, true);
    return offest;
    // 递归获取 offset, 可以考虑使用 getBoundingClientRect
    function getOffset(node, init) {
      // 非Element 终止递归
      if (node.nodeType !== 1) {
        return;
      }
      _position = window.getComputedStyle(node)['position'];
      // position=static: 继续递归父节点
      if (typeof(init) === 'undefined' && _position === 'static') {
        getOffset(node.parentNode);
        return;
      }
      offest.top = node.offsetTop + offest.top - node.scrollTop;
      offest.left = node.offsetLeft + offest.left - node.scrollLeft;
      // position = fixed: 获取值后退出递归
      if (_position === 'fixed') {
        return;
      }
      getOffset(node.parentNode);
    }
  }

-------------------------------------------------------------------分割线  下面为思路

 

实现原理,页面一进来时,我就获取窗口的高度,给最外层的div设置一个最小高度,这样就算窗口压小了,页面还能维持原来的高度,可以滚动浏览:

let initWindowHeight=window.innerHeight
let wrapDiv=document.getElementsByClassName('animated-router-forward-enter-done')[0]
wrapDiv.style.minHeight =initWindowHeight+'px'

 

第二步,滚到红线处

  由于我们不能直接知道软键盘什么时候出来,不过软键盘出来的时候窗口高度会缩小,所以我们可以通过监听窗口大小变化事件来判断软键盘是否弹出,比如浏览器窗口高度突然缩小25%以上,那么我们就认为是软键盘出来了,然后我们获取聚焦input距离页面顶部的距离,计算距离红线有多少距离,假设距离是60,那么我们就让页面向上滚动60,这时input就刚刚好到了红线处;

window.onresize=function(){
if(initWindowHeight-window.innerHeight>initWindowHeight/4&&document.querySelectorAll(':focus').length>0){
if(offset(document.querySelectorAll(':focus')[0]).top>initWindowHeight/4){
document.body.scrollTop=offset(document.querySelectorAll(':focus')[0]).top-initWindowHeight/4
}
}else if(window.innerHeight-initWindowHeight<20){
document.body.scrollTop=0
}

 

 

 在react页面中引入js并调用:

 import {pageInputScroll} from '../../util/pageInputScroll'
......
componentDidMount(){
pageInputScroll()
}

 

备注

offset()方法是使用js实现类似jquery的offset()的一个方法,参考自:原生js实现offset方法

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
React Native 中,当键盘弹出时,会遮挡输入框,这是一个常见的问题。你可以通过以下几种方式来解决: 1. 使用 KeyboardAvoidingView 组件 React Native 提供了 KeyboardAvoidingView 组件,可以自动调整页面的布局,以避免键盘遮挡输入框。你可以将输入框放在 KeyboardAvoidingView 组件中,然后设置 behavior 属性来控制布局的调整方式。例如: ``` import { KeyboardAvoidingView, TextInput } from 'react-native'; <KeyboardAvoidingView behavior={'padding'} style={{ flex: 1 }}> <TextInput style={{ height: 40, borderColor: 'gray', borderWidth: 1 }} /> </KeyboardAvoidingView> ``` 2. 使用 ScrollView 组件 如果页面上有多个输入框,你可以将它们放在一个 ScrollView 组件中,并在键盘弹出时滚动到当前输入框的位置上。你可以使用 scrollTo 方法来实现这个功能。例如: ``` import { ScrollView, TextInput } from 'react-native'; class MyComponent extends React.Component { constructor(props) { super(props); this.state = { inputHeight: 40, }; this.scrollView = React.createRef(); this.textInput = React.createRef(); } componentDidMount() { this.keyboardDidShowListener = Keyboard.addListener( 'keyboardDidShow', this.keyboardDidShow ); this.keyboardDidHideListener = Keyboard.addListener( 'keyboardDidHide', this.keyboardDidHide ); } componentWillUnmount() { this.keyboardDidShowListener.remove(); this.keyboardDidHideListener.remove(); } keyboardDidShow = (event) => { const keyboardHeight = event.endCoordinates.height; const scrollResponder = this.scrollView.current.getScrollResponder(); const inputHandle = ReactNative.findNodeHandle(this.textInput.current); const inputPosition = this.state.inputHeight + 10; scrollResponder.scrollResponderScrollNativeHandleToKeyboard( inputHandle, inputPosition, true ); }; keyboardDidHide = () => { const scrollResponder = this.scrollView.current.getScrollResponder(); scrollResponder.scrollResponderScrollTo({ x: 0, y: 0, animated: true, }); }; render() { return ( <ScrollView ref={this.scrollView} keyboardDismissMode="interactive" contentContainerStyle={{ flexGrow: 1 }} > <TextInput ref={this.textInput} style={{ height: this.state.inputHeight }} onFocus={() => this.setState({ inputHeight: 100 })} onBlur={() => this.setState({ inputHeight: 40 })} /> <TextInput ref={this.textInput} style={{ height: this.state.inputHeight }} onFocus={() => this.setState({ inputHeight: 100 })} onBlur={() => this.setState({ inputHeight: 40 })} /> </ScrollView> ); } } ``` 在上面的例子中,我们使用 ScrollView 组件包裹了两个 TextInput 组件,并且在 KeyboardDidShow 和 KeyboardDidHide 事件中,调用了 ScrollView 组件的 scrollTo 方法来滚动到当前输入框的位置上。 以上是两种比较常用的解决方法,你可以根据具体的场景选择适合自己的方式来解决问题
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值