阅读 3615

【移动端兼容性问题集锦】兼容性问题及解决方案

移动端兼容性总结篇。遇到新的问题,将持续更新

背景介绍

最近半年一直在做移动端h5,主要环境为微信、和app内的WebView。期间遇到很多不同系统和设备的兼容性问题,希望在这整理成集锦,便于日后查找。当然,如果你也刚好遇到同样的问题,希望对你有所帮助。

1. 音视频问题

为什么会放在开头,因为音视频的兼容问题确实挺多的

自动播放

  1. ios safariiPhone Safari中不支持,但在webview中可能被开启;iOS开发文档明确说明蜂窝网络下不允许autoplay;
  2. chrome中,设置mouted后可以自动播放
  3. 微信中不允许自动播放。但是可以借助WeixinJSBridge实现

单例问题

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

循环播放

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

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

<!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

  1. preload,ios下是不支持的。通用的方法是对视频进行play()后立即停止
  2. ios视频自动全屏播放:设置内联属性playsinline webkit-playsinline

2. 海报生成-html2Canvas

营销场景和裂变过程中,我们需要将页面内容一部分作为图片整体分享出去。大部分情况下会用到

html2Canvas

如果只是简单的二维码加海报图,建议直接用drawImg,而不是用和这个插件

2.1 图片跨域

解决方案:需设置useCORS:true

  1. html2canvas提供的proxy方案
    await html2canvas(eleImgBox, {
      // 前提是,请求的图片本身是支持跨域请求的(可能需要后端设置)
      proxy: 'https://aliyun-oss.61info.cn'
    })
复制代码
  1. nginx做域名转发即可
  2. 像二维码这种,可以考虑base64格式的图片

3. 经典的1px边框

一般是采用伪元素模拟的方式,原理:把原先元素的 border 去掉,然后利用 :before 或者 :after 重做 border ,并 transform 的 scale 缩小一半,原先的元素相对定位,新做的 border 绝对定位。

  .scale{
    position: relative;
    border:none;
  }
  .scale:after{
    content: '';
    position: absolute;
    bottom: 0;
    background: #000;
    width: 100%;
    height: 1px;
    transform: scaleY(0.5);
    transform-origin: 0 0;
  }
复制代码

具体几种方法见:

关于移动端开发1px边框的一些理解及解决办法

4. android,border-radius:50%不圆

具体是因为,使用了rem布局,在部分机型上出现的问题,设置具体的px数值,不用50%即可

5. android里line-height不居中

解决方案:来源互联网

  1. 把字号内外边距等设置为需求大小的2倍,使用transform进行缩放。(不适用)
  2. 把字号内外边距等设置为需求大小的2倍,使用zoom进行缩放,可以完美解决。(可以)
  3. 把line-height设置为0,使用padding值把元素撑开,说是可以解决(不适用)。

具体原因Android浏览器下line-height垂直居中为什么会偏离

6. 安卓部分版本input的placeholder偏上

input的line-height设为normal

  input{
      line-height:normal;
  }
复制代码

原理看stackoverflow上的回答:

HTML5 placeholder css padding

7. ios的body设置overflow:hidden仍然可以滚动

一般在所有元素最外层再包一个大盒子.wrap

  .wrap{
      position:relative;
      overflow:hidden;
  }
复制代码

stackoverflow上有好几种处理方法,可以顺便参考下:

Does overflow:hidden applied to work on iPhone Safari?

8. ios 滚动不流畅

使用了absolute布局之后,ios会发现元素内的滚动非常不流畅,滑动的手指松开后,滚动立刻停止,失去了原本的流畅滚动特性。百度一下弹性滚动的问题,发现在 webkit 中,下面的属性可以恢复弹性滚动。

-webkit-overflow-scrolling: touch;
复制代码

9. ios fixed问题

这种常见的布局,但是用ios下当键盘弹起时fixed会失效。解决办法在下面文章里:

Web移动端Fixed布局的解决方案

就是把页面滚动改为容器内滚动。

10. 点透问题

也来说说touch事件与点击穿透问题

首先想到的是fastclick.js这个库,但是是否真的需要,详情看看这篇文章

fastClick 在 touchend 阶段 调用 event.preventDefault,然后通过 document.createEvent 创建一个 MouseEvents,然后 通过 event​Target​.dispatch​Event 触发对应目标元素上绑定的 click 事件

11. 键盘遮挡输入框问题

解决方案如下:

移动web页面,input获取焦点弹出系统虚拟键盘时,挡住input,求解决方案?

12. 浮层上进行滑动,浮层下面的页面也跟着滚动

web移动端浮层滚动阻止window窗体滚动JS/CSS处理

具体就是当浮层出现、隐藏的时候,设置相应的overflow值

13. ios日期转换NAN问题

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

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

14. ios滚动时动画停止

移动端滚动懒人推荐使用better-scroll,很好的插件

ios滚动动画停止的原因及其他解决办法:CSS3 动画在 iOS 上为什么会因为页面滚动也停止?

15. 长按闪退

    element {
        -webkit-touch-callout:none;
    }
复制代码

16. 禁止数字识别为电话号码

   <meta name = "format-detection" content = "telephone=no">
复制代码

17. transition闪屏

  .box { 
       -webkit-transform-style: preserve-3d; 
       -webkit-backface-visibility: hidden; 
       -webkit-perspective: 1000; 
  }
复制代码

18. CSS3动画卡顿

尽量使用transform,避免使用height,width,margin,padding等。可以开启GPU硬件加速,但用硬件加速的时候也要注意,因为这个也有坑,不合理使用反而会让应用越来越卡!

CSS3硬件加速也有坑

19. margin bottom

典型的bug,其实这个bug大家都有办法解决,直接使用padding-bottom就好了。

20. 滚动动画

juejin.cn/post/689701…

21. iphoneX

const isIphonex = () => {
  // X XS, XS Max, XR
  const xSeriesConfig = [
    {
      devicePixelRatio: 3,
      width: 375,
      height: 812,
    },
    {
      devicePixelRatio: 3,
      width: 414,
      height: 896,
    },
    {
      devicePixelRatio: 2,
      width: 414,
      height: 896,
    },
  ];
  // h5
  if (typeof window !== 'undefined' && window) {
    const isIOS = /iphone/gi.test(window.navigator.userAgent);
    if (!isIOS) return false;
    const { devicePixelRatio, screen } = window;
    const { width, height } = screen;
    return xSeriesConfig.some(item => item.devicePixelRatio === devicePixelRatio && item.width === width && item.height === height);
  }
  return false;
}
复制代码

22. 移动端滑动穿透

弹框的内容明显长过屏幕,需要弹框内容滑动,主页页面不滑动

<script type="text/javascript">
  //解决遮罩层滚动穿透问题,分别在遮罩层弹出后和关闭前调用
  const ModalHelper = ( (bodyCls) =>{
    let scrollTop;
    return {
      afterOpen: function () {
        scrollTop = document.scrollingElement.scrollTop;
        document.body.classList.add(bodyCls);
        document.body.style.top = -scrollTop + 'px';
      },
      beforeClose: function () {
        document.body.classList.remove(bodyCls);
        // scrollTop lost after set position:fixed, restore it back.
        document.scrollingElement.scrollTop = scrollTop;
      }
    };
  })('dialog-open');
</script>

body.dialog-open {
  position: fixed;
  width: 100%;
}
复制代码

原理:弹出弹框时,使背景主页内容作为固定定位,这样页面的滑动对其就没有任何影响,关闭弹框使,移除这个固定定位的类名,回复正常

PS:欢迎交流学习,不足之处,尽请指出。

文章分类
前端
文章标签