zoukankan      html  css  js  c++  java
  • react在安卓下输入框被手机键盘遮挡问题

    问题概述

      今天遇到了一个问题,在安卓手机上,当我要点击输入“店铺名称”时,手机软键盘弹出来刚好把输入框挡住了;挡住就算了,关键是页面还不能向上滑动,整个手机窗口被压为原来的二分之一左右;

        

    然后

      然后找了一些方案,不过不大适用,或者是有点麻烦;所以需要整合一下,
      首先,我想一下我要实现的效果

    想要实现的效果

        
      如图,当手机键盘出现时,页面是可以自由滚动的,而且当前聚焦的输入框往红线处靠齐,这样就刚好在剩下的窗口的垂直正中间,这样就不会出现输入框被挡住,看不到自己输入的内容了 ;

    第一步,使屏幕压小时,页面内容可以滚动查看

      如下图所示,黑色框代表屏幕,蓝色框代表页面大小,当屏幕被压小时,页面内容必须保持原来的高度:
        

      实现原理,页面一进来时,我就获取窗口的高度,给最外层的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
            }
            
        };
    

    完整代码

      因为可能有多个页面要调用,所以我把代码放到一个单独的js文件中:

    function pageInputScroll() {
        
        let initWindowHeight=window.innerHeight
        setTimeout(() => {
          let wrapDiv=document.getElementsByClassName('animated-router-forward-enter-done')[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(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
            }
            
        };
    }
    function 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);
        }
    }
    
    export {pageInputScroll};
    

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

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

    备注

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

      

      

      推荐一个可以扫描商品条码进行商品评论的小程序

      

      

  • 相关阅读:
    Java 过滤器的作用
    TreeView的绑定
    设计模式(一)工厂模式Factory(创建型)
    【剑指offer】员工年龄排序
    Spring3.0 AOP 具体解释
    IT行业新名词--透明手机/OCR(光学字符识别)/夹背电池
    MYSQL C API 记录
    Hibernate的介绍
    数据绑定(八)使用Binding的RelativeSource
    一、ExtJS下载使用
  • 原文地址:https://www.cnblogs.com/thing/p/9558248.html
Copyright © 2011-2022 走看看