更多
更多

移动端之fixed定位和虚拟键盘冲突的问题

最近在做的一个手机应用,fixed的大坑像是修水管一样,这里拧紧了那里松,想来是因为对解析原理的不理解,所以看了网上特别多的解决方案之后决定总结一下常见冲突情况的解决方式。

被页面fixed定位虐了两轮,又来填坑( ⊙ o ⊙ )!

根本性的解决原理就是把定位元素和滚动元素从文档流的角度上彻底分离,然乎滚动和固定元素互不影响

之前并没有截图备份,这里的bug截图打算引用别人的图示说明问题即可。

做手机页面时,对于顶部和底部样式的处理,我们会经常使用到display:absolute或者display:fixed来做定位处理,比如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<body class="layout-scroll-fixed">
<!-- fixed定位的头部 -->
<header>

</header>

<!-- 可以滚动的区域 -->
<main>
<div class="content">
<!-- 内容在这里... -->
</div>
</main>

<!-- fixed定位的底部 -->
<footer>
<input type="text" placeholder="Footer..."/>
<button class="submit">提交</button>
</footer>
</body>

但是当页面中出现输入框需要唤起手机中的软键盘输入文字是,这些定位元素就会出现错乱排列问题。

图片

ios下fixed失效原因

软键盘唤起后,页面的 fixed 元素将失效(ios认为用户更希望的是元素随着滚动而移动,也就是变成了 absolute 定位),既然变成了absolute,所以当页面超过一屏且滚动时,失效的 fixed 元素就会跟随滚动了。

解决方案

使用绝对定位和容器内部滚动条来实现固定定位的效果。

即不让页面滚动,将固定定位的部分和其他部分区分开各自内部滚动。

1
2
3
4
5
6
7
8
9
10
main {
/* main绝对定位,进行内部滚动 */
position: absolute;
top: 50px;
bottom: 34px;
/* 使之可以滚动 */
overflow-y: scroll;
/* 增加该属性,可以增加弹性 */
-webkit-overflow-scrolling: touch;
}

另外一种解决方案

即软键盘弹出时监测页面的窗口一旦变化就切换定位方式

1
2
3
4
5
6
7
8
var oHeight = $(document).height(); //浏览器当前的高度
$(window).resize(function(){
if($(document).height() < oHeight){
$("#footer").css("position","static");
}else{
$("#footer").css("position","absolute");
  }
});

这个方案使用后项目的测试组都正常,但是用户反馈回来一个oppo手机还是有问题==!

后来专门找来一个oppo手机发现事实上它很多时候读取的window值为0

因为这个时候我也没oppo手机所以没有做过多测试,但是猜测我们可以利用

navigator.userAgent检测手机型号针对性做更多的事情,或者除了window的改变,我们可以尝试监测更多的window.innerHeight的变化做判断……

阅读

移动端踩坑之旅-ios下fixed、软键盘相关问题总结

移动端 Web 开发踩坑之旅

移动端web页面使用position:fixed问题总结

感谢阅读
公众号