• h5软键盘挡住输入框问题解决(android)


    问题

    移动端浏览器中的表单在部分android机型上测试,点击靠下的输入框时会遇到弹出的软键盘挡住输入框问题
    ios可自身弹起(ios自身的调整偶尔也会出问题,例如第三方键盘会遮挡,原因是第三方输入法的tool bar或者键盘也被当做可视区域,这里不做讨论)

    问题分析及解决办法确立

    最常见的是使用两个方法:scrollIntoViewIfNeeded()scrollIntoView(),使用方法自行百度。在我这里无效。

    经测试发现android弹出键盘时有两种效果:

    1.将activity挤压,键盘也占一部分activity空间;

    2.键盘弹出在浏览器上面覆盖一层,不影响浏览器大小。

    第二种会出现遮挡问题

    于是想到以下两种方案:

    1.通过动态增加页面高度设置scrollTop来使输入框到达合适的位置

    2.设置相对定位,通过top来使输入框到达合适的位置

    影响实现的两个点:

    1.js拿不到键盘的弹出和收起事件;

    2.覆盖一层的键盘弹出方式不会触发window.resize事件和onscroll事件。

    解决

    第一种经试验有些问题影响了实现,这里只讨论第二种。

    直接上代码,这里是react项目(css设置absolute配合js改变top实现效果,transition过渡增强用户体验,这里就不放了)

      getElementOffsetTop(el) {
        let top = el.offsetTop
        let cur = el.offsetParent
        while(cur != null){
              top += cur.offsetTop
              cur = cur.offsetParent
       }
       return top
      }
    
      componentDidMount() {
        const u = navigator.userAgent
        const isAndroid=u.indexOf('Android')>-1||u.indexOf('Linux')>-1;//android终端
        // alert('android'+isAndroid)
        if(isAndroid){ // android统一处理,不影响ios的自身处理
          const body = document.getElementsByTagName('body')[0] // 兼容获取body
    
          const regDom = document.querySelector('.wrapper_register') // 获取页面根元素
          const content = document.querySelector('.content') // 表单内容部分
    
          // const scrollHeight = body.scrollHeight // 网页文档高
          // const scrollTop = body.scrollTop// 卷上去的高
    
          const clientHeight = body.clientHeight //可见高
          const fixHeight = clientHeight/3 // 定位高,弹出键盘时input距浏览器上部的距离,自己定义合适的
    
          // 符合需弹出键盘的元素query
          const queryStr = 'input[type="text"], input[type="tel"], input[type="password"], textarea'
          const inputs = content.querySelectorAll(queryStr)
    
          // console.log(inputs)
    
          const offsetTopArr = Array.prototype.map.call(inputs,item=>{
            return this.getElementOffsetTop(item) // offsetTop只能获取到顶部距它的offsetParent的距离,需此方法获取到元素距顶部的距离
          })
    
          inputs.forEach((item, i)=>{
            item.addEventListener('focus',()=>{
              // 改变top上移页面
              regDom.style.top = '-' + (offsetTopArr[i] - fixHeight) + 'px'
            })
    
            item.addEventListener('blur',()=>{
              // 恢复top
              regDom.style.top = 0
            })
          })
        }
      }
    

    效果基本实现,这里还有两个问题:

    第一,如果下面的提交按钮是fixed,有些手机键盘弹出时会把按钮顶上来,如果上述代码中fixHeight设置不合适,会导致这个按钮遮挡输入框。所以为了统一效果,将底部按钮取消fixed,随页面滚动。

    第二,如果点击键盘上的收起键盘按钮,会导致页面top无法恢复,因为没有触发输入框失焦方法,需点击空白处恢复。(目前没找到解决办法)

    后续

    1.由于android弹出键盘存在一定延迟,所以可以给top更改添加setTimeout,设置合适的延迟时间。

    2.两个h5框架,iScroll、Native.js(虽然在这个问题上没啥用)

    3.最终奥义:修改设计稿,三招 -> 使输入框不在页面的下半部分、采用分页设计、弹出输入层(ps:要和产品和设计沟通,客户不一定会让步 0.0)

    希望大家斧正,交流更好地解决方案,谢谢

  • 相关阅读:
    关于项目中的已发现的难点
    怎样与用户有效地沟通以获取用户的真实需求?
    面向过程(或者叫结构化)分析方法与面向对象分析方法到底区别在哪里?请根据自己的理解简明扼要的回答。
    当下大部分互联网创业公司为什么都愿意采用增量模型来做开发?
    第二次作业
    第一次作业
    第二次博客作业
    第一次博客作业
    第二次博客作业
    第一次博客作业
  • 原文地址:https://www.cnblogs.com/macq/p/10519267.html
Copyright © 2020-2023  润新知