找回密码
 会员注册
查看: 16|回复: 0

H5项目踩坑及出坑实践

[复制链接]

5

主题

0

回帖

16

积分

新手上路

积分
16
发表于 2024-10-9 15:31:53 | 显示全部楼层 |阅读模式
H5项目踩坑及出坑实践 H5项目踩坑及出坑实践 于少芳@贝壳找房 贝壳产品技术 贝壳产品技术 “贝壳产品技术公众号”作为贝壳官方产品技术号,致力打造贝壳产品、技术干货分享平台,面向互联网/O2O开发/产品从业者,每周推送优质产品技术文章、技术沙龙活动及招聘信息等。欢迎大家关注我们。 242篇内容 2020年09月17日 16:11 相比于PC项目只需要关注功能实现,H5项目兼容性似乎是前端开发和测试童鞋需要重点关注的问题。我做H5项目也有一段时间了,下面从自己项目中遇到的问题稍稍做一下复盘,回顾一下踩坑和出坑的过程。1 iphoneX系列手机适配问题表现头部刘海两侧区域或者底部区域,出现刘海遮挡文字遮挡、点击区域,或者呈现黑底或白底空白区域。产生原因iPhoneX及以上版本手机都采用了状态栏、圆弧展示角、传感器槽、主屏幕指示器和屏幕边缘手势(具体名词注释看下图)。头部底部侧边栏都需要做特殊处理,使得content尽可能的处于安全区域内,适配iPhoneX系列手机的特殊性。解决方案设置安全区域,填充危险区域,危险区域不做操作和内容展示。何为安全区域(safe Area),顾名思义,安全区域即为正常显示内容的区域,但该区域不受状态栏和其它内容影响。当界面显示在屏幕上时,安全区域即为导航栏、选项卡栏、工具栏和其他父视图不覆盖的屏幕视图的一部分。具体操作Step1:viewport-fitviewport-fit meta 标签设置为 cover,获取所有区域填充。判断设备是否属于iPhone X,给头部底部增加适配层 。viewport-fit 有 3 个值,分别为:auto:此值不影响初始布局视图端口,并且整个web页面都是可查看的。contain:视图端口按比例缩放,以适合显示内嵌的最大矩形。cover:视图端口被缩放以填充设备显示。强烈建议使用safe area inset变量,以确保重要内容不会出现在显示之外。viewport-fit meta标签设置(cover时)>Step2:增加适配层WebKit包含了新的CSS函数constant()和env(),以及一组四个预定义的常量:safe-area-inset-left, safe-area-inset-right, safe-area-inset-top和 safe-area-inset-bottom。当合并一起使用时,允许样式引用每个方面的安全区域的大小。当我们设置viewport-fit:contain,也就是默认的时候时;设置safe-area-inset-left, safe-area-inset-right, safe-area-inset-top和 safe-area-inset-bottom等参数时不起作用的。只有设为cover才可以用contant()和env()方法。当我们设置viewport-fit:cover时,为了达到向前兼容ios11.2以前的版本向后兼容ios11.2以后版本的浏览器,需要同时用contant()和env()。设置如下:body{padding-top:constant(safe-area-inset-top);padding-top:env(safe-area-inset-top);//为导航栏+状态栏的高度88pxpadding-left:constant(safe-area-inset-left);padding-left:env(safe-area-inset-left);//如果未竖屏时为0padding-right:constant(safe-area-inset-right);//如果未竖屏时为0padding-right:env(safe-area-inset-right);padding-bottom:constant(safe-area-inset-bottom));//距离底部圆弧的距离34pxpadding-bottom:env(safe-area-inset-bottom));}通过上述设置,可以开辟出适配iPhoneX系列手机的安全区域。在实际应用中,为了解决底部出现文字遮挡、fixed按钮不可点击,或者呈现黑底或白底空白区域的问题,同时适配不同的宽高比。结合媒体查询分别适配X,XS MAX ,XR,给底部fixed的元素加一个适配底部小黑条和圆角的底部高度,如下面fixed-footer,会出现底部body超出底部fixed部分的问题,可以给body加一句,使得每个X的屏幕都有一个div块,把内容顶上去,防止出现底部透传现象。//iphoneX@mediaonlyscreenand(device-width:375px)and(device-height:812px)and(-webkit-device-pixel-ratio:3){.fixed-footer{bottom:constant(safe-area-inset-bottom);bottom:env(safe-area-inset-bottom);}.footer{position:fixed;bottom:0;width:100%;height:constant(safe-area-inset-bottom)height:env(safe-area-inset-bottom)background-color:#fff;}}//iphoneXsMax@mediaonlyscreenand(device-width:414px)and(device-height:896px)and(-webkit-device-pixel-ratio:3){.fixed-footer{bottom:constant(safe-area-inset-bottom)bottom:env(safe-area-inset-bottom)}.footer{position:fixed;bottom:0;width:100%;height:constant(safe-area-inset-bottom)height:env(safe-area-inset-bottom)background-color:#fff;}}//iphoneXR@mediaonlyscreenand(device-width:414px)and(device-height:896px)and(-webkit-device-pixel-ratio:2){.fixed-footer{bottom:constant(safe-area-inset-bottom)bottom:env(safe-area-inset-bottom)}.footer{position:fixed;bottom:0;width:100%;height:constant(safe-area-inset-bottom)height:env(safe-area-inset-bottom)background-color:#fff;}}2 click点击延迟与穿透问题表现延时:点击某个滚动的动画(如图所示),交互中动画会停止,出现下一步操作。但是在IOS系统中,点击没有反应,与Android效果差别很大。穿透:点击蒙层,蒙层消失后发现触发了蒙层下层元素点击事件。或者点击页内按钮跳转至新页,发现新页的对应位置的click事件被触发了。产生原因为什么会出现click延时?iOS 中的 safari,为了实现双击缩放操作,在单击300ms之后,如果未进行第二次点击,则执行click单击操作。也就是说来判断用户行为是否为双击缩放产生的。后来其他的浏览器都效仿safari,实现了双击缩放功能,导致在大部分app中无论是否需要双击缩放这种行为,click单击都会产生300ms延迟。为什么会出现点击透传?当点击移动设备的屏幕时, 可以分解成多个事件,顺序依次为:touchstart — touchmove — touchend — click, 这些事件是按顺序依次触发的。双层元素叠加时,在上层元素上绑定 touch 事件,下层元素绑定 click 事件。由于 click 发生在touch之后,点击上层元素,元素消失,此时事件只进行到touchend,300ms后下层元素会触发 click事件,由此产生了点击穿透的效果。当然对于跨页面点击穿透问题,和上述原理差不多,同时满足了touch,跳转新页面,click事件,三者缺一不可。解决方案解决click延时:a. 禁止缩放//关键是user-scalable=no但是在iOS10下面及部分UC浏览器中为了提高网站的辅助功能那个,屏蔽了Meta下的user-scalable=no功能。就算加上user-scalable=no,浏览器也能支持手动缩放。可以用js加监听事件来阻止手动缩放。代码如下:window.onload=function(){document.addEventListener('touchstart',function(event){if(event.touches.length>1){event.preventDefault();}})varlastTouchEnd=0;document.addEventListener('touchend',function(event){varnow=(newDate()).getTime();if(now-lastTouchEnd这句话定义了本页面的viewport的宽度为设备宽度,初始缩放值和最大缩放值都为1,并禁止了用户缩放。viewport的设置和屏幕物理分辨率是按比例而不是相同的,移动端window对象有个devicePixelRatio属性,它表示设备物理像素和css像素的比例,在retina屏的iphone手机上,这个值为2或3, css里写的1px长度映射到物理像素上就有2px或3px。通过设置viewport,可以改变css中的1px用多少物理像素来渲染,设置了不同的viewport,当然1px的线条看起来粗细不一致。解决方案a. 在公共样式里面定义一个类,使用伪元素+绝对定位+scale,优点:兼容性较好,缺点:input元素不支持伪元素内容区域设置四周的边框:.wrapheight:40px;position:relative;&::aftercontent:"";position:absolute;top:0;left:0;width:200%;height:200%;transform-origin:00;-webkit-transform-origin:00;-moz-transform-origin:00;-o-transform-origin:00;transform:scale(.5);-webkit-transform:scale(.5);-moz-transform:scale(.5);-o-transform:scale(.5);border:1pxsolid#ebebf0;b.使用 rem 改进使用rem作为单位,这样可以更好地去实现移动端的响应式像素以及Retina屏幕上的表现。优点是实现简单,缺点是部分机型还是不兼容。c. css中引入 svg 改进具体思路是为元素加上 background-image,然后把svg置为图片类型,因为svg上的 1px 就是实实在在的只占1个物理像素。实现很简单,代码如下:input{background-image:url("data:image/svg+xml;base64,");}4 position fixed和sticky兼容性表现在如下图所示的图中,当页面滑动到搜索框下面,二手房tab会自动吸顶,但是在某些安卓机的原生浏览器中没有吸顶这个动作。产生原因吸顶的动作是用position:sticky完成的,但是Caniuse上显示sticky的兼容性如下:Sticky的作用相当于relative和fixed的结合体,当修饰的目标节点再屏幕中时表现为relative,当要超出的时候是fixed的形式展现。但是由于兼容性问题,在安卓端没有很好地兼容。且它的活动范围只能在父元素内,滚动超过父元素的话,它一样不能吸顶。解决方案react解决方案:使用react-sticky,通过计算 组件相对于组件的位置进行工作,如果他出现在视口的外面,将其附加到屏幕的顶部所需要的样式作为参数传递给render callback,作为child传递的函数。JS解决方案:通过cssSupport判断浏览器的支持情况,如果浏览器支持sticky,则不做处理,否则通过自定义滚动事件的监听,根据top的改变来实现tab层fixed和absolute的转换。vue解决方案:可以直接使用vue-sticky组件,vue-sticky实现原理大致与JS解决方案差不多。5 软键盘将页面顶起来、收起未回落问题表现在Android手机中,点击input框时,键盘弹出,将页面顶起来,导致页面样式错乱。失去焦点时,键盘收起,键盘区域空白,未回落。产生原因我们在app布局中会有个固定的底部。在Android一些版本中,输入键盘弹出来,会将解压absolute和fixed定位的元素。导致可视区域变小,布局错乱。解决方案软键盘将页面顶起来的解决方案,主要是通过监听页面高度变化,强制恢复成弹出前的高度。//记录原有的视口高度constoriginalHeight=document.body.clientHeight||document.documentElement.clientHeight;window.onresize=function(){varresizeHeight=document.documentElement.clientHeight||document.body.clientHeight;if(resizeHeight=674&+version[1]>=12){window.scrollTo(0,Math.max(document.body.clientHeight,document.documentElement.clientHeight));}window.scrollTo(x-coord,y-coord),其中window.scrollTo(0,clientHeight)恢复成原来的视口6 总结H5项目有的坑远不止这些,出坑解决方案更是个人有个人的偏好。后续会持续输出相关踩坑出坑方案。生命不息,踩坑不止......7 推荐文章吃透移动端 H5 与 Hybrid|实践踩坑12种问题汇总https://juejin.im/post/5dfadb91e51d45584006e486#heading-21基于Vue的移动端h5项目总结https://juejin.im/post/5de72b1f51882512360d3910#heading-17App适配IPhoneX----Safe Area (安全区域)https://www.jianshu.com/p/da6332417fa0移动端常见的问题--click点击延时解决方案https://blog.csdn.net/weixin_46113485/article/details/104567528移动端click事件延迟300ms解决方案https://www.jianshu.com/p/eabbc714a9c7解决iOS10的Safari下Meta设置user-scalable=no无效的方法https://www.jianshu.com/p/1a2270c3a1c7聊聊移动端的适配问题https://juejin.im/post/6844904197050073095 预览时标签不可点 FE33大前端69FE · 目录#FE上一篇koa-session源码解读下一篇秒懂Javascript浮点数精度缺失原理关闭更多小程序广告搜索「undefined」网络结果
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-31 04:21 , Processed in 0.495080 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表