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 pagination插件实现无刷新分页代码
Oct 13 Javascript
javascript通过class来获取元素实现代码
Feb 20 Javascript
jquery 删除字符串最后一个字符的方法解析
Feb 11 Javascript
window.print打印指定div指定网页指定区域的方法
Aug 04 Javascript
js表格排序实例分析(支持int,float,date,string四种数据类型)
May 06 Javascript
JS字符串的切分用法实例
Feb 22 Javascript
jQuery 翻页组件yunm.pager.js实现div局部刷新的思路
Aug 11 Javascript
用jquery快速解决IE输入框不能输入的问题
Oct 04 Javascript
基于Vue的文字跑马灯组件(npm 组件包)
May 24 Javascript
angularJS实现不同视图同步刷新详解
Oct 09 Javascript
灵活使用console让js调试更简单的方法步骤
Apr 23 Javascript
解析原生JS getComputedStyle
May 25 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
Zend Framework页面缓存实例
2014/06/25 PHP
PHP生成压缩文件实例
2015/02/07 PHP
PHP文件下载实例代码浅析
2016/08/17 PHP
php加密之discuz内容经典加密方式实例详解
2017/02/04 PHP
js中的onchange和onpropertychange (onchange无效的解决方法)
2014/03/08 Javascript
jQuery拖动div、移动div、弹出层实现原理及示例
2014/04/08 Javascript
JavaScript实现文本框中默认显示背景图片在获得焦点后消失的方法
2015/07/01 Javascript
jQuery mobile 移动web(4)
2015/12/20 Javascript
Easyui ueditor 整合解决不能编辑的问题(推荐)
2017/06/25 Javascript
JavaScript实现的超简单计算器功能示例
2017/12/23 Javascript
node.js博客项目开发手记
2018/03/16 Javascript
父组件中vuex方法更新state子组件不能及时更新并渲染的完美解决方法
2018/04/25 Javascript
详解angular脏检查原理及伪代码实现
2018/06/08 Javascript
vue利用v-for嵌套输出多层对象,分别输出到个表的方法
2018/09/07 Javascript
angularJS自定义directive之带参方法传递详解
2018/10/09 Javascript
layer.open 获取不到表单信息的解决方法
2019/09/26 Javascript
python发送邮件接收邮件示例分享
2014/01/21 Python
在Python中用split()方法分割字符串的使用介绍
2015/05/20 Python
浅谈numpy库的常用基本操作方法
2018/01/09 Python
解决Python一行输出不显示的问题
2018/12/03 Python
python用类实现文章敏感词的过滤方法示例
2019/10/27 Python
使用python脚本自动生成K8S-YAML的方法示例
2020/07/12 Python
Python 使用 PyQt5 开发的关机小工具分享
2020/07/16 Python
基于python实现坦克大战游戏
2020/10/27 Python
Python Django路径配置实现过程解析
2020/11/05 Python
CSS3绘制圆角矩形的简单示例
2015/09/28 HTML / CSS
美国折扣网站:jClub
2017/08/07 全球购物
viagogo波兰票务平台:演唱会、体育比赛、戏剧门票
2018/04/23 全球购物
iHerb中文官网:维生素、保健品和健康产品
2018/11/01 全球购物
大学考试作弊检讨书
2014/01/30 职场文书
五年级音乐教学反思
2014/02/06 职场文书
勤俭节约演讲稿
2014/05/08 职场文书
节能减耗标语
2014/06/21 职场文书
2014年信贷员工作总结
2014/11/18 职场文书
基层医务人员三严三实心得体会
2016/01/05 职场文书
python index() 与 rindex() 方法的使用示例详解
2022/12/24 Python