前端系列——与众不同的移动端底部固定栏 fixed、absolute 兼容 iOS 和 Android 方案

本文主要是介绍前端系列——与众不同的移动端底部固定栏 fixed、absolute 兼容 iOS 和 Android 方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

相信我,我分享的和你在其他博客上看到的终极方案是如此的与众不同!

做过移动端开发的同学,对底部DOM定位出现的各种奇葩情况已经深恶痛绝了吧,底部DOM设置不同的position,在Android和ios上表现都不一样。

为了兼容Android和ios,很多人都煞费苦心,也包括我。

打开你做的H5,尤其是在微信上打开看看,是不是觉得很恶心,如果自我感觉很恶心,那么请往下看这篇文章,不恶心说明你成功了,可以走了!

最终还是成功解决了,这篇文章记录一下兼容2种设备的方案。

第一种情况

据我所知,网上还找不到一个能够真正解决这个问题的教程,因为大多数人都是只考虑在body scroll的情况下,设置底部为fixed或者absolute,然后设置滚动区域padding-bottom的值,这种做法反正我是无法接受的,体验太不爽了,也没有兼容Android和ios。

下图是第一种情况,滚动区域有表单,底部一个固定栏,当填写表单的时候,我们看看ios和Android的表现情况:

1、底部定位为fixed的情况下

ios:激活输入框时,底部不会弹出来(合理)。
Android:激活输入框时,底部会跟着输入框弹出来(不合理)。

2、底部定位为absolute的情况下

ios:激活输入框时,底部不会弹出来(合理)。
Android:激活输入框时,底部会跟着输入框弹出来(不合理)。

android后遗症:输入框失焦的时候,可能导致底部显示在浏览器中间某个位置,回不到原位置。

absolute后遗症:底部按钮和输入框区域一起随着body滚动,不再置顶独立。当滚动区域超过一屏幕时,底部输入框定位出现错乱。

clipboard.png

传统解决办法

通常将底部设置为fixed,当激活输入框的时候,将底部定位改为relative,即可兼容ios和Android。

第二种情况

底部如果是个输入框的情况下,我们肯定需要输入框在激活的时候弹出来,和第一种情况是相反的。

1、底部定位为fixed的情况下

ios:激活输入框时,底部不会弹出来(不合理)。
Android:激活输入框时,底部会跟着输入框弹出来(合理)。

2、底部定位为absolute的情况下

ios:当滚动区域超过一屏幕时,底部输入框定位出现错乱(不合理)。
Android:当滚动区域超过一屏幕时,底部输入框定位出现错乱(不合理)。

clipboard.png

传统解决办法:

仍旧是采用fixed定位

ios:在激活输入框的时候,执行下面代码

setTimeout(() => document.body.scrollTop = document.body.scrollHeight, 500)

android: 表现正常

传统解决方案的后遗症

除了抖动问题,还有就是微信端滚动body会显示微信浏览器背景,也就是超出滚动边界回弹效应,还有一个恶心的问题是当有弹框的时候,弹框和body滚动累加的双重滚动会有点击穿透造成的卡顿问题。

由此,如果你还寄希望于body滚动,那么你的移动端开发体验真的一塌糊涂。

搭建真正的移动端滚动架构

看到这里,你可以暂时把上面的传统解决方案统统忘记。

下面我将会分享移动端最舒适的架构方案。

1、你可能听过Iscroll,这个东西是我们今天要用到的框架的鼻祖,但我们不是用它,而是我曾经另外一篇文章介绍到的JRoll框架(比IScroll更加轻量和兼容的移动端滚动框架)。

2、使用这款框架对我们解决底部定位问题还有优化弹框体验有什么帮助呢?他可以完美解决传统解决方案的后遗症,因为他并不是使用body滚动,而是使用css3滚动,采用GPU加速,在ios和Android上测试并不卡顿。如果你想做出像app一样流程的H5,别再用那恶心的body滚动了。

源码(复制查看效果,别忘了导入js插件)

下面的源码你可以直接复制到一个html文件上测试,代码中我提供了多种功能的解决方案:

1、采用滚动框架时,何时获取滚动区域的高度(看源码)

2、输入框底部固定时,在该框架中兼容ios和Android的方法(看源码)

3、采用DocumentFragment动态渲染5000个列表元素,说到这个有点意思,记得腾讯某部门的社招面试题就是考察这个知识点,一般人可能采用的是for循环加innerHTML的方法(看源码)

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=0.5, minimum-scale=0.5, maximum-scale=0.5, user-scalable=no"><title>Title</title><style>* {padding: 0;margin: 0;}body, html {font-size: 24px;height: 100%;}ul {padding-bottom: 1rem;}ul li {list-style: none;}.bottom {position: fixed;bottom: 0;left: 0;width: 100%;height: 4.0833rem;}.bottom > input {width: 100%;border: 0;outline: 0;background: rgb(246, 246, 246);color: rgb(255, 255, 255);text-align: center;line-height: 4.0833rem;font-size: 1.25rem;}</style>
</head>
<body>
<div id="scroll-body"><ul></ul>
</div>
<div class="bottom"><input type="text" placeholder="请输入内容" onfocus="evocation()"></div>
<script src="./js/jroll.js"></script>
<script>function getClientHeight() {
//        获取移动端屏幕高度var winHeightif (window.innerHeight) {winHeight = window.innerHeight;} else if ((document.body) && (document.body.clientHeight)) {winHeight = document.body.clientHeight;} else if (document.documentElement && document.documentElement.clientHeight && document.documentElement.clientWidth) {winHeight = document.documentElement.clientHeight;}return winHeight}var scrollBody = document.querySelector('#scroll-body') //获取滚动区域的DOMvar bottom = document.querySelector('.bottom') //获取底部DOMfunction renderLi() {//渲染li列表,采用DocumentFragment方案var ul = document.querySelector('ul')var dFrag = document.createDocumentFragment()var startTime = new Date().getTime()for (var i = 0; i < 5000; i++) {var li = document.createElement("li")li.textContent = idFrag.appendChild(li)}ul.appendChild(dFrag)var endTime = new Date().getTime()console.log('渲染耗时:', endTime-startTime, 'ms')}function evocation() {//ios唤出弹框,Android的不需要setTimeout(() => document.body.scrollTop = document.body.scrollHeight, 500)}renderLi()document.addEventListener('DOMContentLoaded', function() {var height = getClientHeight() - bottom.offsetHeight //获取滚动区域高度scrollBody.style.height = height + 'px' //计算出实际的滚动区域的高度,然后设置new JRoll(scrollBody) //实例化JRoll插件})
</script>
</body>
</html>

总结

使用上面提供的框架,你在移动端开发中,不再需要担心底部固定的问题,不再需要担心滚动造成的一系列问题,不再需要担心弹框滚动以及点击弹框造成的穿透问题等。

而且,不知道你发现没有,底部固定栏你现在可以尝试使用fixed、absolute、relative等设置,不再局限于只能使用fixed了。感兴趣就好好研究一下代码吧!

但是

在IOS11版本中,我发现了document.body.scrollTop = document.body.scrollHeight无效的bug,目前还没找到原因,小于IOS11一切正常。

这里也封装了React版本的插件,可以下载使用:react-roll-container

转载https://segmentfault.com/a/1190000012310521

这篇关于前端系列——与众不同的移动端底部固定栏 fixed、absolute 兼容 iOS 和 Android 方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/509401

相关文章

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2

Ubuntu固定虚拟机ip地址的方法教程

《Ubuntu固定虚拟机ip地址的方法教程》本文详细介绍了如何在Ubuntu虚拟机中固定IP地址,包括检查和编辑`/etc/apt/sources.list`文件、更新网络配置文件以及使用Networ... 1、由于虚拟机网络是桥接,所以ip地址会不停地变化,接下来我们就讲述ip如何固定 2、如果apt安

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

CSS弹性布局常用设置方式

《CSS弹性布局常用设置方式》文章总结了CSS布局与样式的常用属性和技巧,包括视口单位、弹性盒子布局、浮动元素、背景和边框样式、文本和阴影效果、溢出隐藏、定位以及背景渐变等,通过这些技巧,可以实现复杂... 一、单位元素vm 1vm 为视口的1%vh 视口高的1%vmin 参照长边vmax 参照长边re

CSS3中使用flex和grid实现等高元素布局的示例代码

《CSS3中使用flex和grid实现等高元素布局的示例代码》:本文主要介绍了使用CSS3中的Flexbox和Grid布局实现等高元素布局的方法,通过简单的两列实现、每行放置3列以及全部代码的展示,展示了这两种布局方式的实现细节和效果,详细内容请阅读本文,希望能对你有所帮助... 过往的实现方法是使用浮动加

css渐变色背景|<gradient示例详解

《css渐变色背景|<gradient示例详解》CSS渐变是一种从一种颜色平滑过渡到另一种颜色的效果,可以作为元素的背景,它包括线性渐变、径向渐变和锥形渐变,本文介绍css渐变色背景|<gradien... 使用渐变色作为背景可以直接将渐China编程变色用作元素的背景,可以看做是一种特殊的背景图片。(是作为背

CSS自定义浏览器滚动条样式完整代码

《CSS自定义浏览器滚动条样式完整代码》:本文主要介绍了如何使用CSS自定义浏览器滚动条的样式,包括隐藏滚动条的角落、设置滚动条的基本样式、轨道样式和滑块样式,并提供了完整的CSS代码示例,通过这些技巧,你可以为你的网站添加个性化的滚动条样式,从而提升用户体验,详细内容请阅读本文,希望能对你有所帮助...

css实现图片旋转功能

《css实现图片旋转功能》:本文主要介绍了四种CSS变换效果:图片旋转90度、水平翻转、垂直翻转,并附带了相应的代码示例,详细内容请阅读本文,希望能对你有所帮助... 一 css实现图片旋转90度.icon{ -moz-transform:rotate(-90deg); -webkit-transfo