移动端h5项目的兼容和适配问题

解决兼容性问题的关键在于对移动端产品的生存环境进行梳理,在此基础之上制定应对策略。

所谓生存环境主要分为三个维度:

硬件环境,细分为品牌和机型,决定了屏幕大小、性能等硬件限制

操作系统,比如iOS6和iOS7,或者安卓各家的定制系统的不同版本

浏览器,主要分为App容器,原生浏览器,各品牌浏览器

为什么要做页面适配?

不同机型的屏幕尺寸、物理像素和逻辑像素都有差异,而ui 的尺寸一一般是固定的,如果都使用px的写法,会导致不同手机上样式的错乱。

如何做页面适配?

什么是像素?像素(Pel,pixel;pictureelement),为组成一幅图像的全部亮度和色度的最小图像单元。单位面积内的像素越多,图像的效果就越好。

什么叫分辨率呢? 屏幕分辨率是指纵横向上的像素点数,单位是px。屏幕分辨率高时(例如 1600 x 1200),在屏幕上显示的像素多,单个像素尺寸比较小.

不同系统的不同浏览器对小数点的px有不同的处理,例如:手机上观察iOS的Chrome会画出0.5px的边,而安卓(5.0)原生浏览器是不行的。所以如果我们把单位设置成小数的px包括宽高等,其实不太可靠,因为不同浏览器表现不一样。

最早的解决方案:rem

rem(font size of the root element)是CSS3新增的一个相对单位,是指相对于根元素的字体大小的单位。flexible 的原理就是这个。

c 复制代码
const scale = root.clientWidth / 10  设备视口宽度,例如375px
root.style.fontSize = scale + 'px'   可自定义根元素的比例,1rem = 37.5px
后续使用的时候,需要转为rem , 可以和less配合使用
/*rem.less*/
@device-width: 375; /*设备布局视口*/
@rem: (@device-width/10rem);

由于viewport单位得到众多浏览器的兼容,lib-flexible这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。建议大家开始使用viewport来替代此方。

解决方案二:vw、vh适配

vw(Viewport Width)、vh(Viewport Height)是基于视图窗口的单位,是css3中提出来的,基于视图窗口的单位。

vh、vw方案即将视觉视口宽度 window.innerWidth和视觉视口高度 window.innerHeight 等分为 100 份。

如果按视觉视口为375px,那么1vw = 3.75px,这时UI给定一个元素的宽为75px(设备独立像素),我们只需要将它设置为75 / 3.75 = 20vw

c 复制代码
// 还是rem.less 我们加一个@vw变量
@device-width: 375;
@rem: (@device-width/10rem);
@vw: (100vw/@device-width);

解决方案三:viewport+PX

这种方案可以让我们在开发时不用关注设备屏幕尺寸的差异,直接按照设计稿上的标注进行开发,也无需单位的换算,直接用px。

在 HTML 的 head 标签里加入

c 复制代码
<meta name="viewport" content="width={设计稿宽度}, initial-scale={屏幕逻辑像素宽度/设计稿宽度}" > 。

export function initViewport() {
    const width = 375;  // 设计稿宽度
    const scale = window.innerWidth / width
    // console.log('scale', scale)
    let meta = document.querySelector('meta[name=viewport]')
    let content = `width=${width}, init-scale=${scale}, user-scalable=no`
    if(!meta) {
        meta = document.createElement('meta')
        meta.setAttribute('name', 'viewport')
        document.head.appendChild(meta)
    }
    meta.setAttribute('content', content)
}

自适应布局方案:

1、媒体查询

2、flex

c 复制代码
 @media screen and (min-device-width:800px) {
         .div div {
             width: 33.3%;
         }
 }

遇到的兼容性问题记录:

问题一 、

自动播放: ios safariiPhone Safari中不支持,但在webview中可能被开启;iOS开发文档明确说明蜂窝网络下不允许autoplay;

chrome中,设置mouted后可以自动播放

微信中不允许自动播放。但是可以借助WeixinJSBridge实现

单例问题

ios safari中的音频对象是单例的,ios中是无法播放多个音频文件的

循环播放

ios部分机型不支持循环播放

解决方案:监听播放完成事件ended,手动触发播放

c 复制代码
<!doctype html>
<html>
<head>
    <title>Looping Audio</title>
    <script type="text/javascript">
        function init() {
            var myAudio = document.getElementById("audio");
            myAudio.addEventListener('ended', loopAudio, false);
        }
        function loopAudio() {
            var myAudio = document.getElementById("audio");
            myAudio.play();
        }
    </script>
</head>
<body onload="init();">
    <audio id="audio" src="myAudio.m4a" controls></audio>
</body>
</html>

问题二 、video 的 preload,ios下是不支持的。

通用的方法是对视频进行play()后立即停止

ios视频自动全屏播放:设置内联属性playsinline webkit-playsinline

问题三 、Android浏览器下line-height垂直居中为什么会偏离?

原因:

推测可能是Android在排版计算的时候参考了primyfont字体的相关属性(即HHead Ascent、HHead Descent等),而primyfont的查找是看font-family里哪个字体在fonts.xml里第一个匹配上,而原生Android下中文字体是没有family name的,导致匹配上的始终不是中文字体,所以解决这个问题就要在font-family里显式申明中文,或者通过什么方法保证所有字符都fallback到中文字体

作者:虎三刀

链接:https://juejin.cn/post/7103835385280593957

来源:稀土掘金

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

ios 的不存在这个情况。安卓下低于12px都会出现渲染上浮的情况

display: flex;

align-items: center;

问题四 、安卓部分版本input的placeholder偏上

input的line-height设为normal

input{

line-height:normal;

}

问题五、ios日期转换NAN问题

具体就是,new Date('2020-11-12 00:00:00')在ios中会为NAN

决绝方案:用new Date('2020/11/12 00:00:00')的日期格式,或者写个正则转换

问题六、windo.open 实现在ios上非用户触发得被拦截

修改交互

问题七、input上传文件multitype在安卓机上存在兼容问题,图片可以选择多个,文件只能选一个(使用企微的api解决,原生能力)

问题八、ios手机上将图片转成base64失败

原因:

转换需要给图片设置允许跨域,但是在ios手机上允许跨域和给src赋值有顺序的区别,在chrome模拟没顺序问题

解决方案:

先给Image对象设置允许跨域,再给Image对象的src赋值

相关推荐
一个处女座的程序猿O(∩_∩)O1 小时前
小型 Vue 项目,该不该用 Pinia 、Vuex呢?
前端·javascript·vue.js
hackeroink4 小时前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
迷雾漫步者5 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-6 小时前
验证码机制
前端·后端
燃先生._.7 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖8 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
m0_748235248 小时前
前端实现获取后端返回的文件流并下载
前端·状态模式
m0_748240259 小时前
前端如何检测用户登录状态是否过期
前端
black^sugar9 小时前
纯前端实现更新检测
开发语言·前端·javascript