HTML5摇一摇以及音频播放问题优化总结

前言感想:不放过任何一个WARNING、ERROR或者不够好的体验点,持续不断优化,精益求精,我们就能够得到提高。

1. 摇一摇不够灵敏、摇动很多次没有响应的问题、

原来摇一摇代码是从网络Copy的,活动上线后,发现部分手机摇一摇监测效果不够灵敏,摇动很多次都没有响应,恨不得把手机砸了,于是优化。

原摇一摇代码:

var SHAKE_THRESHOLD = 800;      
var last_update = 0;        
var x = y = z = last_x = last_y = last_z = 0;

function deviceMotionHandler(eventData) {       
    var acceleration = eventData.accelerationIncludingGravity;      
    var curTime = new Date().getTime();     

    if ((curTime - last_update) > 500) {        
        var diffTime = curTime - last_update;       
        last_update = curTime;      
        x = acceleration.x;     
        y = acceleration.y;     
        z = acceleration.z;     
        var speed = Math.abs(x + y + z - last_x - last_y - last_z) / diffTime * 10000;      
        var status = document.getElementById("status");     

        if (speed > SHAKE_THRESHOLD) {  
          alert('摇一摇显示');
        }

        last_x = x;     
        last_y = y;     
        last_z = z;     
    }       
}

if(window.DeviceMotionEvent) {
    // Mobile browser support motion sensing events
    window.addEventListener('devicemotion',deviceMotionHandler,false);
} else {
    // Mobile browser does not support the motion sensing events
}

于是开始研究起上面的代码不够灵敏的原因,发现:

The device motion event is a superset of the device orientation event; it returns data about the rotation information and also acceleration information about the device. The acceleration data is returned in three axes: x,y and z. They are measured in meters per second squared (m/s^2). Because some devices might not have the hardware to exclude the effect of gravity,the event returns two properties,accelerationIncludingGravity and acceleration,which excludes the effects of gravity,(when this is the case,the acceleration data will be null)

原来HTML5对设备移动有两个加速度相关的数据:

// Grab the acceleration from the results
  var acceleration = eventData.acceleration;
  info = xyz.replace("X",acceleration.x);
  info = info.replace("Y",acceleration.y);
  info = info.replace("Z",acceleration.z);
  document.getElementById("moAccel").innerHTML = info;

  // Grab the acceleration including gravity from the results
  acceleration = eventData.accelerationIncludingGravity;
  info = xyz.replace("X",acceleration.z);
  document.getElementById("moAccelGrav").innerHTML = info;

于是,优化后代码如下:

var SHAKE_THRESHOLD = 300,last_update = 0,x = y = z = last_x = last_y = last_z = 0,function deviceMotionHandler(eventData) {
    var acceleration = eventData.accelerationIncludingGravity;
    var curTime = new Date().getTime();

    if ((curTime - last_update) > 500) {   //多次移动事件中取两个点的事件间隔
        var diffTime = curTime - last_update;
        last_update = curTime;

        x = acceleration.x;
        y = acceleration.y;
        z = acceleration.z;
        //var speed = Math.abs(x + y + z - last_x - last_y - last_z) / (diffTime * 1000);

        //主要优化点1:原来的计算方式把x、y、z三方向的移动有可能会互相干扰。比如x往真方向,y往负方向,就互相抵消了。
        var dist = Math.sqrt((x-last_x)*(x-last_x)+(y-last_y)*(y-last_y)+(z-last_y)*(z-last_y))
        var speed = dist/diffTime*10000;

        //优化点2:摇动速度测试调整,达到最优
        if (speed > SHAKE_THRESHOLD) {     //摇一摇灵敏度
           alert('摇一摇显示');
        }
        last_x = x;
        last_y = y;
        last_z = z;
    }
}

参考链接:http://www.html5rocks.com/en/tutorials/device/orientation/

2.页面报WARNING:The devicemotion event is deprecated on insecure origins,and support will be removed in the future. You should consider switching your application to a secure origin,such as HTTPS.

上面的 devicemotion发现会报如上警告,查了一些资料,目前木有办法解决,除非切换到https。

3. ERROR: Uncaught (in promise) DOMException: The element has no supported sources.错误

原来的插入audio的源码如下,播放音频的时候在浏览器和调试器的debug环境会报如上错误,但是不影响iPhone等手机的使用

<audio  id="audio" src="http://awp.qq.com/act/a20160315live/shake_sound_male.mp3">
    </audio>

    function playOrPaused() {
        console.log(typeof audio);
        console.log(typeof audio.paused);

        if (audio.paused) {
            audio.play(); //ERROR:Uncaught (in promise) DOMException: The element has no supported sources.
        }
    }

查阅相关资料发现audio可以支持两种方式设置src,如下:

1. Permitted content: If the element has a src attribute: zero or more <track> elements,followed by transparent content that contains no media elements — that is,no <audio> or <video> elements.

2. Else: zero or more <source> elements,followed by zero or more <track> elements,followed by transparent content that contains no media elements,that is no <audio> or <video> elements.

并且:src嵌入的音频的URL。 该URL应遵从 HTTP access controls. 这是一个可选属性;你可以在audio元素中使用 元素来替代该属性指定嵌入的音频。

于是改成第二种方案,解决问题,如下:

<audio id="audio">   
      <source src="http://ossweb-img.qq.com/images/lol/m/act/a20160315live/shake_sound_male.mp3" type="audio/mpeg">
      Your browser does not support the audio tag.
    </audio>

参考资料:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio
https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/audio
http://www.w3schools.com/html/html5_audio.asp

4. 部分安卓机(如vivo)在微信浏览器里面audio播放不了、没有声音,但是在手机自带的浏览器没问题

解决方案:

```
document.addEventListener('WeixinJSBridgeReady',function () {

        audio = document.getElementById("audio");

        if (window.DeviceMotionEvent) {
            window.addEventListener('devicemotion',false);
        } else {
            alert('本设备不支持devicemotion事件');
            return ;
        }

        shakeOn(1000);//摇一摇动画示例
});

```

5. WARNING: Deferred long-running timer task(s) to improve scrolling smoothness. See crbug.com/574343.

setTimeout(function () {
        shakeOff();
    },n);

在原关闭摇一摇动画效果中,发现有时候debug调试器反馈如山WARNING,通过查资料发现:

The warning is telling you that your timer wasn’t fired on time because it is a long running callback (> 50ms) and the user was/is about to scroll. While your callback is running,Chrome can’t start scrolling the page so this results in “jank”,user input not being handled in a timely manner. To make the experience better for the user,Chrome decided to postpone firing that callback until a time where running it won’t negatively affect the user.

I don’t know the details of what you’re trying to do,but the correct way to do things would be to chunk up your one big callback into smaller batches and spread them out so that any one call will not noticeably delay user actions. You could additionally look at using requestIdleCallback which will call your function only when Chrome is idle and is ideally suited for non-time critical tasks. (However,requestIdleCallback is supported only on Chrome as of now).

参考资料:http://stackoverflow.com/questions/37048438/what-is-this-console-warning-i-keep-getting-deferred-long-running-timer-tasks

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


HTML5和CSS3实现3D展示商品信息的代码
利用HTML5中的Canvas绘制笑脸的代码
Html5剪切板功能的实现
如何通过HTML5触摸事件实现移动端简易进度条
Html5移动端获奖无缝滚动动画实现
关于HTML5和CSS3实现机器猫的代码
HTML5使用DOM进行自定义控制
使用HTML5 Canvas绘制阴影效果的方法
使用PHP和HTML5 FormData实现无刷新文件上传
如何解决HTML5 虚拟键盘出现挡住输入框的问题
HTML5中div和section以及article的区别分析
html5和CSS 实现禁止IOS长按复制粘贴功能
html5 touch事件实现触屏页面上下滑动
canvas 模拟实现电子彩票刮刮乐的代码
HTML5 Plus 实现手机APP拍照或相册选择图片上传的功能
Android自定义环形LoadingView效果
HTML5 canvas绘制五角星的方法
html5使用html2canvas实现浏览器截图
使用Canvas处理图片的方法介绍
利用Canvas模仿百度贴吧客户端loading小球的方法