记录一下最近遇到的两个小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
事件。
因为focusin
和focusout
支持冒泡,对应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端则是整个添加了一个评论的浮层,总来来说也是一个不错的方案。

最后介绍一个神奇的东西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 |
缺点:
- html和body的滚动都禁止了,弹出层关闭后,会丢失原有的滚动位置,需要用JS来还原
- 有些页面的北京还有能滚的动的效果
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 // 滚动到相应位置,确保兼容性} |
参考
来源:https://www.cnblogs.com/liuzhongrong/p/12371468.html