移动端兼容问题

266 阅读5分钟

移动端开发在兼容方面有很多需要注意的地方,我觉得兼容问题需要归纳成一个字典,不是很难的技术问题,却需要大家时常补充,并且查漏补缺

以下是整理后的一些兼容问题

1、前缀

前缀问题在pc端开发也会出现,原因是各大浏览器厂商一直在实施css3,但是有些属性还没有成为真正的标准,所以各大浏览器厂商就以前缀方式定义

我们一般的写法如下,w3c的实现标准在最后一个,当这个属性成为标准以后,前缀就可以舍弃了

-webkit-transform:rotate(-3deg); /*为Chrome/Safari*/ 
-moz-transform:rotate(-3deg); /*为Firefox*/ 
-ms-transform:rotate(-3deg); /*为IE*/ 
-o-transform:rotate(-3deg); /*为Opera*/ 
transform:rotate(-3deg); /*为nothing*/
前缀浏览器内核
-ms-IE浏览器Trident内核
-moz-FirefoxGecko内核
-o-OperaPresto内核
-webkit-Chrome和SafariWebkit内核

那我们现在开发的时候好像没写这么多的前缀呢,原因是可以检查一下我们的构建工具有没有引入类似autoprefixer之类的插件,它可以自动地添加 CSS 前缀,我们只用关注w3c标准就好了

2、ios安全区域

现如今苹果发布的很多手机取消了物理按键,大大提升了手机的颜值,这些手机的特点就是多了刘海,底部小黑条,圆角,我们开发的时候就要特别关注了,比如我们的底部tab和底部小黑条重叠怎么办,顶部的刘海让我们元素显示不全了,所以我们在开发的时候就要把我们的内容放在一个安全区域内

viewport-fit是专门为了这个问题诞生的一个属性,它用于限制网页如何在安全区域内进行展示。

  • contain: 可视窗口完全包含网页内容(左边),这就意味着横屏左右两边有白边
  • cover:网页内容完全覆盖可视窗口(右边)
  • 默认情况下或者设置为autocontain效果相同

image.png 我们需要用cover属性解决这个问题,iOS11新增了两个CSS函数env、constant,用于设定安全区域与边界的距离。

函数内部可以是四个常量:

  • safe-area-inset-left:安全区域距离左边边界距离
  • safe-area-inset-right:安全区域距离右边边界距离
  • safe-area-inset-top:安全区域距离顶部边界距离
  • safe-area-inset-bottom:安全区域距离底部边界距离

我们必须指定viweport-fit后才能使用这两个函数:

<meta name="viewport" content="viewport-fit=cover">

这里还要注意一个问题,constantiOS < 11.2的版本中生效,enviOS >= 11.2的版本中生效,所以为了兼容所有版本,需要把两个都写上才有用

比如我们写底部导航栏时

.tab { 
    padding-bottom: constant(safe-area-inset-bottom); 
    padding-bottom: env(safe-area-inset-bottom); 
}
3、点击事件300ms延迟

iOS 中的 safari,为了实现双击缩放操作,在单击 300ms 之后,如果未进行第二次点击,则执行 click 单击操作。也就是说来判断用户行为是否为双击产生的。但是,在 App 中,无论是否需要双击缩放这种行为,click 单击都会产生 300ms 延迟。

4、点击穿透

事件触发顺序: touchstarttouchmovetouchendclick

如果有双层元素,上层元素是蒙层,下层元素是a标签,在上层元素上绑定 touch 事件,下层元素绑定 click 事件。由于 click 发生在 touch 之后,点击上层元素,元素消失,下层元素会触发 click 事件,由此产生了点击穿透的效果。

解决思路1:用touchstart事件替换掉click事件

一般情况下没有问题,但是如果出现既有click事件又有touchmove事件,我们可能本意在touchmove时不想触发click,由于使用touchstart事件就会优先触发,所以呢,在具有滚动的情况下,还是建议使用 click 处理。

解决思路2:fastclick.js

原理:在检测到touchend事件的时候,会通过DOM自定义事件立即触发模拟一个click事件,并把浏览器在300ms之后真正的click事件阻止掉

5、useragent判断

在移动端开发的过程中,很多时候要针对不同的设备类型给出不同的跳转页面,比如判断ios,andriod,微信等等

var ua = navigator.userAgent.toLowerCase().toString();
6、时间兼容

ios上不支持转化2023-05-06 09:00:00 这种格式的时间,需要改成2023/05/06 09:00:00

7、ios滚动不流畅

iOS 5.0 以及之后的版本,滑动有定义有两个值 auto 和 touch,默认值为 auto

-webkit-overflow-scrolling: touch; /* 当手指从触摸屏上移开,会保持一段时间的滚动 */
-webkit-overflow-scrolling: auto; /* 当手指从触摸屏上移开,滚动会立即停止 */
8、默认样式

移动端不同浏览器对元素的margin,padding有自己的定义,还有一些比如a标签,按钮都有自己的样式,所以我们开发的时候为了统一需要消除默认样式,一般通过reset.css(自定义清除样式表)清除,下面还有些需要特别注意的

9、ios默认输入框内有阴影,清除阴影
input,textarea {
  border: 0; // 方法1
  border-color: transparent; // 方法2
  -webkit-appearance: none; // 方法3
  appearance: none;
}
10、a标签、input标签、button标签点击后产生蓝色边框
a,button,input,textarea { 
   outline:none;
   -webkit-tap-highlight-color: rgba(0,0,0,0); 
}   
11、通过transform进行skew变形,rotate旋转会造成出现锯齿现象
.test {
   transform: rotate(-4deg) skew(10deg) translateZ(0);
   outline: 1px solid rgba(255,255,255,0)
}
12、iOS 浏览器横屏时会重置字体
body {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    -moz-text-size-adjust: 100%;
}
13、禁止复制、选中文本
.el {
  -webkit-user-select: none;
  -moz-user-select: none;
  -khtml-user-select: none;
   user-select: none;
}
14、input的placeholder属性在文本位置上偏上

line-height:normal

15、移动端video、audio标签中的autoplay失效

由于安卓和ios系统禁止自动播放和js自动触发,必须是用户去触发生效

document.addEventListener('touchstart',function() {
  document.getElementsByTagName('audio')[0].play();
  document.getElementsByTagName('audio')[0].pause();
});
16、特殊的meta
<meta content="telephone=no" name="format-detection">  忽略将数字变为电话号码
<meta content="email=no" name="format-detection">   忽略识别email
<meta content="yes" name="apple-mobile-web-app-capable"> IOS中safari允许全屏浏览
<meta name="full-screen" content="yes"> uc横屏
<meta name="x5-fullscreen" content="true"> qq横屏