react在安卓中输入框被手机键盘遮挡问题的解决方法


Posted in Javascript onSeptember 03, 2018

前言

React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站。做出来以后,发现这套东西很好用,就在2013年5月开源了。

本文主要介绍了关于react在安卓输入框被键盘遮挡的相关内容,分享出来动大家参考学习,下面话不多说了,来一起看看详细的介绍吧

问题概述

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

react在安卓中输入框被手机键盘遮挡问题的解决方法

然后

然后找了一些方案,不过不大适用,或者是有点麻烦;所以需要整合一下,

首先,我想一下我要实现的效果(2018/9/3补充:评论区有更加简单的实现方法)

想要实现的效果

react在安卓中输入框被手机键盘遮挡问题的解决方法

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

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

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

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){
   //offset是封装好的一个获取元素距离页面顶部滚动距离的方法
   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()
 }

如果只是想在安卓下使用,可以加一个判断:

if(/Android/i.test(navigator.userAgent)){
  pageInputScroll()
 }

效果动图

我在pc端的谷歌浏览器模拟一下实现的效果:

react在安卓中输入框被手机键盘遮挡问题的解决方法

备注

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

总结:

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
基于jQuery的仿flash的广告轮播代码
Nov 04 Javascript
关于js datetime的那点事
Nov 15 Javascript
JS注释所产生的bug 即使注释也会执行
Nov 19 Javascript
理解javascript中的回调函数(callback)
Sep 02 Javascript
jQuery实现二级下拉菜单效果
Jan 05 Javascript
关于JavaScript中forEach和each用法浅析
Jul 27 Javascript
Angular.js初始化之ng-app的自动绑定与手动绑定详解
Jul 31 Javascript
对vue中methods互相调用的方法详解
Aug 30 Javascript
如何从零开始手写Koa2框架
Mar 22 Javascript
TypeScript中的方法重载详解
Apr 12 Javascript
Vue自定义全局Toast和Loading的实例详解
Apr 18 Javascript
elementUI vue this.$confirm 和el-dialog 弹出框 移动 示例demo
Jul 03 Javascript
Vue 中对图片地址进行拼接的方法
Sep 03 #Javascript
VUE预渲染及遇到的坑
Sep 03 #Javascript
详解vue通过NGINX部署在子目录或者二级目录实践
Sep 03 #Javascript
vue的style绑定background-image的方式和其他变量数据的区别详解
Sep 03 #Javascript
vue完成项目后,打包成静态文件的方法
Sep 03 #Javascript
vue填坑之webpack run build 静态资源找不到的解决方法
Sep 03 #Javascript
webpack4 处理CSS的方法示例
Sep 03 #Javascript
You might like
php cookie 作用范围?不要在当前页面使用你的cookie
2009/03/24 PHP
PHP 字符串正则替换函数preg_replace使用说明
2011/07/15 PHP
使用php+Ajax实现唯一校验实现代码[简单应用]
2011/11/29 PHP
php冒泡排序、快速排序、快速查找、二维数组去重实例分享
2014/04/24 PHP
以实例全面讲解PHP中多进程编程的相关函数的使用
2015/08/18 PHP
Javascript中的isNaN函数使用说明
2011/11/10 Javascript
jQuery对象数据缓存Cache原理及jQuery.data方法区别介绍
2013/04/07 Javascript
JS Replace()的高级使用方法介绍
2013/06/29 Javascript
JS中操作JSON总结
2020/12/06 Javascript
Node.js的MongoDB驱动Mongoose基本使用教程
2016/03/01 Javascript
JS实现的表格行上下移动操作示例
2016/08/03 Javascript
初识简单却不失优雅的Vue.js
2016/09/12 Javascript
利用BootStrap弹出二级对话框的简单实现方法
2016/09/21 Javascript
jQuery快速实现商品数量加减的方法
2017/02/06 Javascript
jQuery插件FusionCharts绘制ScrollColumn2D图效果示例【附demo源码下载】
2017/03/22 jQuery
vue引入ueditor及node后台配置详解
2018/01/03 Javascript
jQuery实现的回车触发按钮事件功能示例
2018/03/25 jQuery
vue.js实现的全选与全不选功能示例【基于elementui】
2018/12/03 Javascript
简单实现python爬虫功能
2015/12/31 Python
Windows中安装使用Virtualenv来创建独立Python环境
2016/05/31 Python
python 数据的清理行为实例详解
2017/07/12 Python
实例详解Matlab 与 Python 的区别
2019/04/26 Python
Python实现二叉树前序、中序、后序及层次遍历示例代码
2019/05/18 Python
梅尔倒谱系数(MFCC)实现
2019/06/19 Python
pyspark给dataframe增加新的一列的实现示例
2020/04/24 Python
Python tkinter实现简单加法计算器代码实例
2020/05/13 Python
python tqdm实现进度条的示例代码
2020/11/10 Python
深入浅析css3 border-image边框图像详解
2015/11/24 HTML / CSS
门卫岗位安全职责
2013/12/13 职场文书
幼儿园优秀教师事迹
2014/02/13 职场文书
考察邀请函范文
2015/01/31 职场文书
办公经费申请报告
2015/05/15 职场文书
生死抉择观后感
2015/06/09 职场文书
生日祝酒词大全
2015/08/10 职场文书
参观监狱警示教育心得体会
2016/01/15 职场文书
详解TS数字分隔符和更严格的类属性检查
2021/05/06 Javascript