总结之移动端开发的兼容问题(倒计时/视频/音频)

2,723 阅读4分钟

已经9102年了,终于想起了2018年年底整理的总结,翻出来炒个冷饭。

一、JS基础

  1. 【文字垂直居中】 安卓机下常见垂直居中偏差,典型机型:华为/小米

    // 1. 最直观的方案
    display: inline-block;
    line-height: 1;  // for ios
    padding: 0 0;
    vertical-align: middle;
    
    // 2. 宽/高/字号设为原来的2倍,通过transform,iOS下有偏差
    height: 2x;
    width: 2x;
    font-size: 2x;
    transform: scale(.5);
    transform-origin: left center;
    
    // 3 目前测试看来兼容最好的
    &:after {
        content: '';
        display: inline-block;
        vertical-align: middle;
        width: 0;
        height: 100%;
        margin-top: 1px;
    }
    
  2. 【babel ios8】 适配ios8+和ie9+的babel转译规则设置

    {
        "preset": [
            ["env", {
               "modules": false,
               "targets": {
                    "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
                }
            }],
            "stage-2"
        ],
        "plugins": ["transform-runtime"]
    }
    

二、倒计时

  • 【锁屏处理】 使用setInterval进行倒计时,锁屏时会中断执行

    document.addEventListener('visibilitychange', ()=>{
        if(document.hidden) { 
            // 页面被挂起
         } else {
            // 页面呼出
            // 校准时间
        }
    })
    
  • 【精准度】 长时间的倒计时不精准,在低端手机下尤其明显
    原因:setTimeout/setInterval本身计时不精准,长时间的误差累加较明显
    解决:进入页面时获取服务器时间和本地时间的差值,服务器时间作为初始时间,用setInterval每隔400毫秒更新一次时间戳作为当前时间,每隔1分钟获取本地时间与进入页面时的本地时间对比作为校准值,校准当前时间。

三、视频

  • 【自动播放】 只有ios10+支持无音轨/设置静音的视频自动播放,其他情况下都需要用户手动触发(click/touchstart事件)。对于无音轨视频,可考虑的降级方案有低端机下用GIF/逐帧动画(GKA工具)代替。
  • 【预加载】 设置preload表示在页面加载后马上加载,个人通常的做法是设置该属性,src置空,在需要播放的时候再设置src,以此达到按需加载的目的。
  • 【微信/部分浏览器video层级】 在安卓机下,微信和部分浏览器中,video总在最顶层,且暂时没有发现覆盖它的方法。微信端目前唯一的解决方法是成为白名单(2019.01.06),浏览器暂时无解。
  • 【iphone默认全屏播放】 在video标签中添加属性<video playsinline="true" -webkit-playsinline="true"></video>
  • 【锁屏处理】 锁屏后应当暂停视频,同采用事件visibilitychange处理。
  • 【浏览器下暂停有广告】 浏览器原生插入的广告,暂时木有办法。可考虑的处理方案是在视频暂停时将视频缩小为1px * 1px用一张图片占位。
  • 【视频资源会发出3次请求】
    • 原因分析详见张鑫旭大佬的分析:www.zhangxinxu.com/wordpress/2…
    • 简述:解释了一下页面中某些video资源会请求3次的原因,文章中修复方案实测有效。除此之外发现使用http链接,请求依旧会有2次,第一次请求的code为307,原因是后台做了强制https访问的限制(基于HSTS),改用https链接问题解决。

四、音频

  • 【自动播放】 需要用户手动触发才可播放

  • 【循环播放有停顿感】 音频的前后衔接最好有淡出淡入,手机原生播放器循环播放音频时会有近1秒的停顿,如果没有淡出淡入会有停顿感。

  • 【音频切换方案】

    • 采用切换audio标签src属性的方法。缺点是在iOS下有一定的延时(因为ios不能缓存音频)

    • 声明多个audio标签把需要的视频预先引入,需要哪个播哪个。缺点是在iOS下一个audio占一个线程,若有多个audio很占资源

    • 将多个音频合并为一个文件,播放音频时只需播放相应时段

      <audio id="audio">
          <source src="http://storage.jd.com/babel-open/1211bumbleBee/hapN.mp3" type="audio/mpeg" />
      </audio>
      <button onclick="playSprite('happy')">Play happy sprite</button>
      <button onclick="playSprite('nervous')">Play nervous sprite</button>
      <script>
          var audioSprite = document.getElementById('audio');
          // sprite data
          var spriteData = {
              happy: {start:0, length:3},
              nervous: {start: 4, length: 3}
          };
          // current sprite being played
          var currentSprite = {};
          var onTimeUpdate = function () {
              if(this.currentTime >= currentSprite.start + currentSprite.length) {
                  audioSprite.currentTime = currentSprite.start;
                  audioSprite.play();
              }
          };
          audioSprite.addEventListener('timeupdate', onTimeUpdate, false);
          var playSprite = function (id) {
              if(spriteData[id] && spriteData[id].length) {
                  currentSprite = spriteData[id];
                  audioSprite.currentTime = currentSprite.start;
                  audioSprite.play();
              }
          };
      </script>
      
  • 【静音】 iOS8及以下,IE9及以下不支持muted属性

  • 【初始化延迟】 iOS Safari浏览器初始化一个新的音频有延时,因为iOS需要实例化一个新的音频对象再通过网络请求音频资源。解决方案是在页面ready之后把每个文件都load,提前预加载。

    $(function() {
        $('#audio1').load();
        $('#audio2').load();
    })
    

广告时间

飞书是字节跳动旗下办公套件产品,其将即时沟通、在线协作、音视频会议、日历、云盘、工作台等功能进行了深度整合,为用户提供一站式协作体验。目前,飞书服务的客户已经覆盖了科技互联网、信息技术、制造、建筑地产、企业服务、教育、媒体等多个领域。欢迎投递字节跳动飞书团队,有海量前端后端HC~扫描二维码或者点击链接投递,认准飞书团队👍~
【校招】内推码: HZNVPHS,投递链接: job.toutiao.com/s/JaeUCoc
【社招】投递链接: job.toutiao.com/s/JaevUNo
社招 校招