移动端虚拟键盘和滚动穿透小结

北城余情 提交于 2020-02-27 12:56:02

记录一下最近遇到的两个小bug,也不算小bug,可能在不同的移动端浏览器表现不同吧。一个是虚拟键盘顶起,一个是滚动穿透问题。

首先需要明确的一点是,虚拟键盘的顶起在IOS端和Android端有很大的不同变现。

监听移动端软键盘弹起和收起

1. Android端 监听resize

1234567891011
var winHeight = $(window).height();$(window).resize(function () {  var thisHeight = $(this).height();  if( winHeight - thisHeight > 140) {      } else {    // 键盘收起  }})

2. IOS端 监听input失焦blur

ios中的键盘或者第三方键盘并不会监听到window resize事件,所以不能用resize监听,所以需要通过输入框是否获取焦点来判断。

在Android中,有一些机型,键盘收起了,输入框仍处于焦点状态,并没有触发focusout事件。

因为focusinfocusout支持冒泡,对应focus和blur,所以根据需求,我们可以选择相应的事件。

1234567
$(document).on('focusin', function () {  //软键盘弹出的事件处理});$(document).on('focusout', function () {  //软键盘收起的事件处理});

input textarea contenteditable="true" 置底问题

这里也需要了解一下,IOS和Android关于fixed属性的支持是不一样的。

1. IOS端

ios中,虚拟键盘顶起来之后,整个页面都会被键盘部分压缩。也就是说页面的高度会变小,并且所有的fixed都会变成absolute

也就是说,之前在ios端fixed到底部的input框等可focus元素,会变成absolute定位,并且随着页面能够滑动。

2. Android端

android端中,虚拟键盘顶起来之后,fixed属性不会失效,唤起的键盘是覆盖在页面上的,不会压缩页面。

项目中的bug及一些思考

在最近的一个项目中,移动端页面布局,因为现在手机的高度不同,简单的背景图并不能放文字了,文字会拉伸,我需要设置一个footer放到底部,这里我最开始考虑的就是用fixed布局到最底部,结果当键盘顶起来的时候,文字也就跟着一起顶上去了,整个页面使用的是overflow: hidden

这里就需要监听键盘顶起事件,并执行相应的给元素添加相关css的功能。

123456789
var oHeight = $(document).height();// 监听键盘事件$(window).resize(function () {  if ($(document).height() < oHeight) {    $('footer').addClass('hide');  } else {    $('footer').removeClass('hide');  }});

另外,关于底部的输入框顶起的问题,我看了一下手机版微博的解决方案,在Android端,虚拟键盘顶起,应该直接是fixed在底部,在IOS端则是整个添加了一个评论的浮层,总来来说也是一个不错的方案。

大专栏  移动端虚拟键盘和滚动穿透小结1253206717.cos.ap-guangzhou.myqcloud.com/little_tricks/ios_input.jpg" alt=""/>

最后介绍一个神奇的东西Element.scrollIntoView(),这个东西能把底部的输入框提高到可视区域,不过经过测试,键盘顶起是需要时间的,我们需要确保,在键盘调起之后,确保元素调用scrollIntoView()

下面是我写的一段代码:

12345
$('#el').on('focus', function () {  setTimeout(() => {    document.querySelector('#el').scrollIntoView();  }, 300);});

滚动穿透

在移动端中,滚动穿透问题很常见,处理起来也比较繁琐。下面我还是按照不同的方法进行分类:

touchmove事件中调用preventDefault()

这个方法适用于,弹出框内容无需滚动。如果弹出层内部有滚动事件,将会导致,弹出层的滚动事件也无法滚动。

添加相关的类

给html上添加一个noscroll的类

12345
.noscroll,.noscroll body  overflow: hidden.noscroll body  poition: relative

缺点:

  1. html和body的滚动都禁止了,弹出层关闭后,会丢失原有的滚动位置,需要用JS来还原
  2. 有些页面的北京还有能滚的动的效果

fixed加上js恢复记录位置

css

1234
body.mask-open {  position: fixed;  width: 100%;}

12345678910111213141516171819
var scrollTop = 0;open.onclick = function() {  scrollTop = document.body.scrollTop || document.documentElement.scrollTop;  document.body.classList.add('mask-open');  document.body.style.top = -scrollTop + 'px'; // 脱离文档流后回到当前位置  mask.style.display = 'block';}close.onclick = function() {  mask.style.display = 'none';  document.body.classList.remove('mask-open');  document.body.scrollTop = document.documentElement.scrollTop = scrollTop // 滚动到相应位置,确保兼容性}

参考

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!