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 相关文章推荐
[原创]用javascript实现检测指定目录是否存在的方法
Jan 12 Javascript
jquery remove方法应用详解
Nov 22 Javascript
Jquery多选下拉列表插件jquery multiselect功能介绍及使用
May 24 Javascript
jquery入门必备的基本认识及实例(整理)
Jun 24 Javascript
js函数在frame中的相互调用详解
Mar 03 Javascript
javascript实现带节日和农历的日历特效
Feb 01 Javascript
浅析node连接数据库(express+mysql)
Nov 30 Javascript
浅谈使用splice函数对数组中的元素进行删除时的注意事项
Dec 04 Javascript
AngularJS中$apply方法和$watch方法用法总结
Dec 13 Javascript
关于Angular2 + node接口调试的解决方案
May 28 Javascript
关于axios如何全局注册浅析
Jan 14 Javascript
elementui之el-tebs浏览器卡死的问题和使用报错未注册问题
Jul 06 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
Access数据库导入Mysql的方法之一
2006/10/09 PHP
php遍历所有文件及文件夹的方法深入解析
2013/06/08 PHP
PHP中的多行字符串传递给JavaScript的两种方法
2014/06/19 PHP
php生成随机颜色方法汇总
2014/12/03 PHP
JS鼠标事件大全 推荐收藏
2011/11/01 Javascript
关于IE BUG与字符串截取substr的解决办法
2013/04/10 Javascript
javascript-简单的计算器实现步骤分解(附图)
2013/05/30 Javascript
node.js中的socket.io入门实例
2014/04/26 Javascript
jQuery实现多按钮单击变色
2014/11/27 Javascript
jQuery中wrapAll()方法用法实例
2015/01/16 Javascript
跟我学习javascript解决异步编程异常方案
2015/11/23 Javascript
详谈jQuery中使用attr(), prop(), val()获取value的异同
2017/04/25 jQuery
JavaScript实现滑动门效果
2020/01/18 Javascript
js抽奖转盘实现方法分析
2020/05/16 Javascript
python开发之文件操作用法实例
2015/11/13 Python
整理Python 常用string函数(收藏)
2016/05/30 Python
Python深度优先算法生成迷宫
2018/01/22 Python
Python格式化输出%s和%d
2018/05/07 Python
python快速编写单行注释多行注释的方法
2019/07/31 Python
python3 selenium自动化 下拉框定位的例子
2019/08/23 Python
python3.7环境下安装Anaconda的教程图解
2019/09/10 Python
python实现图像随机裁剪的示例代码
2020/12/10 Python
SIXPAD智能健身仪英国官网:革命性的训练装备品牌
2018/09/27 全球购物
英国文具、办公用品和科技商店:Ryman
2018/09/27 全球购物
美国演唱会和体育门票购买网站:Ticketnetwork
2018/10/19 全球购物
一名毕业生的自我鉴定
2013/12/04 职场文书
公司庆典活动邀请函
2014/01/09 职场文书
追悼会上的答谢词
2014/01/10 职场文书
《祁黄羊》教学反思
2014/04/22 职场文书
国际贸易毕业生求职信
2014/07/20 职场文书
教师优秀党员事迹材料
2014/08/14 职场文书
2014年教研员工作总结
2014/12/23 职场文书
药品销售员2015年终工作总结
2015/10/22 职场文书
2016年“12.4”法制宣传日活动总结
2016/04/01 职场文书
SpringBoot工程下使用OpenFeign的坑及解决
2021/07/02 Java/Android
SQL实现LeetCode(197.上升温度)
2021/08/07 MySQL